1

I have the following Javascript where I parse data attributes from DOM objects. I want to zip those two arrays into one, so I get a multidimensional (in this case 2D) array with [[id1, atr1], [id2, atr2], ...]
However, this code below gives me a 1D array with all the ids followed by all the attributes.

I als tried to use map(element, index) producing the same result.
Can someone help me to zip this correctly?

var currentHTML = $('.product');
var currentId = $("body").find('.product').toArray().map(function(e){return $(e).attr("data-id-product");});    
var currentAtr = $("body").find('.product').toArray().map(function(e){return $(e).attr("data-id-product-attribute");}); 
currentHTMLMap = [];

for(i = 0;i < currentId.length; i++) {
    currentHTMLMap.push(currentId[i], currentAtr[i]);
}

Here is how the two 1D arrays could look like:

currentId: ["1", "6"]
currentAtr: ["1", "0"]

Screenshot of my console showing the jQuery 'created' arrays:

enter image description here

ItFreak
  • 2,299
  • 5
  • 21
  • 45

3 Answers3

1

You used Array.push which takes element1[, ...[, elementN]] and push them all to the end of the array. You need to push a new array with both elements within. To fix that write currentHTMLMap.push([currentId[i], currentAtr[i]]); (note the extra brackets that wrap the two elements).
However, you could also use Array.map which is more elegant.

var currentId = ["1", "6"];
var currentAtr = ["1", "0"];
var currentHTMLMap = currentId.map(function(e, i) {
  return [e, currentAtr[i]]
});

console.log(currentHTMLMap); // [[1,1], [6,0]]

By the way, looking your whole example, you could simply do this:
Important to use double brackets since jQuery unwrap the first brackets.

var currentHTMLMap = $('.product').map(function(i, e) {
  var $element = $(e);
  return [
    [$element.attr("data-id-product"), $element.attr("data-id-product-attribute")]
  ];
}).toArray();

console.log(currentHTMLMap); // [[1,1], [6,0]]
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="product" data-id-product="1" data-id-product-attribute="1">
</div>
<div class="product" data-id-product="6" data-id-product-attribute="0">
</div>
Maor Refaeli
  • 2,417
  • 2
  • 19
  • 33
  • I did that myself too, but I get no zipped array. See my screenshot of my jQuery arrays in the console, maybe I am missing something – ItFreak Oct 04 '18 at 10:29
  • when I do typeof currentHTMLMap I get object – ItFreak Oct 04 '18 at 10:29
  • `typeof currentHTMLMap` will return `object` for an array :) [This](https://stackoverflow.com/a/20956445/1918287) is how you check if object is an array – Maor Refaeli Oct 04 '18 at 10:38
0

consider the follwing:

let arr = [];
let arr1 = ["a","b"];
let arr2 = ["c","d"];

for(i = 0;i < arr1.length; i++) {
    arr.push([arr1[i], arr2[i]]);
}

console.log(arr);

will produce:

[ [ 'a', 'b' ], [ 'c', 'd' ] ]

iLuvLogix
  • 5,920
  • 3
  • 26
  • 43
0

You don't need jQuery for this, but you could pull in a library called Ramda

<span class="product" data-id-product="1" data-id-product-attribute="foo"></span>
<span class="product" data-id-product="2" data-id-product-attribute="bar"></span>

<script>
  // globally define DOM variables
  const products = Array.from(document.querySelectorAll('.product'));
  const currentIds = products.map(e => e.dataset.idProduct);    
  const currentAtrs = products.map(e => e.dataset.idProductAttribute); 
</script>

<!-- import a single function for modern browsers -->
<script type="module">
  import zip from 'https://unpkg.com/ramda@0.25.0/es/zip.js?module';
  const currentHTMLMap = zip(currentIds, currentAtrs)
  console.log(currentHTMLMap)
</script>

<!-- load the minified bundle for old browsers -->
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js" integrity="sha256-YN22NHB7zs5+LjcHWgk3zL0s+CRnzCQzDOFnndmUamY=" crossorigin="anonymous"></script>
<script nomodule>
  const currentHTMLMap = R.zip(currentIds, currentAtrs);
  console.log(currentHTMLMap)
</script>
Benny Powers
  • 5,398
  • 4
  • 32
  • 55