简体   繁体   中英

Javascript zip jQuery arrays into one

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:

在此处输入图片说明

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>

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' ] ]

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM