I have 2 arrays:
var a = [1, 2, 3]
var b = [a, b, c]
What I want to get as a result is:
[[1, a], [2, b], [3, c]]
It seems simple but I just can't figure out.
I want the result to be one array with each of the elements from the two arrays zipped together.
Use the map
method:
var a = [1, 2, 3] var b = ['a', 'b', 'c'] var c = a.map(function(e, i) { return [e, b[i]]; }); console.log(c)
Using Array.prototype.map()
const zip = (a, b) => a.map((k, i) => [k, b[i]]); console.log(zip([1,2,3], ["a","b","c"])); // [[1, "a"], [2, "b"], [3, "c"]]
Using Array.from()
const zip = (a, b) => Array.from(Array(Math.max(b.length, a.length)), (_, i) => [a[i], b[i]]); console.log( zip([1,2,3], ["a","b","c","d"]) ); // [[1, "a"], [2, "b"], [3, "c"], [undefined, "d"]]
Using Array.prototype.fill() and Array.prototype.map()
const zip = (a, b) => Array(Math.max(b.length, a.length)).fill().map((_,i) => [a[i], b[i]]); console.log(zip([1,2,3], ["a","b","c","d"])); // [[1, "a"], [2, "b"], [3, "c"], [undefined, "d"]]
const zip = (...arr) => Array(Math.max(...arr.map(a => a.length))).fill().map((_,i) => arr.map(a => a[i])); console.log(zip([1,2], [3,4], [5,6])); // [[1,3,5], [2,4,6]]
You can also use a generator function to zip()
.
const a = [1, 2, 3] const b = ['a', 'b', 'c'] /** * Zips any number of arrays. It will always zip() the largest array returning undefined for shorter arrays. * @param {...Array<any>} arrays */ function* zip(...arrays){ const maxLength = arrays.reduce((max, curIterable) => curIterable.length > max ? curIterable.length: max, 0); for (let i = 0; i < maxLength; i++) { yield arrays.map(array => array[i]); } } // put zipped result in an array const result = [...zip(a, b)] // or lazy generate the values for (const [valA, valB] of zip(a, b)) { console.log(`${valA}: ${valB}`); }
.as-console-wrapper { max-height: 100% !important; top: 0; }
The above works for any number of arrays and will zip()
the longest array so undefined
is returned as a value for shorter arrays.
Iterables
Here a function which can be used for all Iterables
(eg Maps
, Sets
or your custom Iterable
), not just arrays.
const a = [1, 2, 3]; const b = ["a", "b", "c"]; /** * Zips any number of iterables. It will always zip() the largest Iterable returning undefined for shorter arrays. * @param {...Iterable<any>} iterables */ function* zip(...iterables) { // get the iterator of for each iterables const iters = [...iterables].map((iterable) => iterable[Symbol.iterator]()); let next = iters.map((iter) => iter.next().value); // as long as any of the iterables returns something, yield a value (zip longest) while(anyOf(next)) { yield next; next = iters.map((iter) => iter.next().value); } function anyOf(arr){ return arr.some(v => v !== undefined); } } // put zipped result in aa array const result = [...zip(a, new Set(b))]; // or lazy generate the values for (const [valA, valB] of zip(a, new Set(b))) { console.log(`${valA}: ${valB}`); }
Obviously it would also be possible to just use
[...Iterable]
to transform anyIterable
to an array and then use the first function.
Using the reduce
method:
const a = [1, 2, 3] const b = ['a', 'b', 'c'] var c = a.reduce((acc, curr, ind) => { acc.push([curr, b[ind]]); return acc; }, []); console.log(c)
With forEach
method:
const a = [1, 2, 3] const b = ['a', 'b', 'c'] const c = []; a.forEach((el, ind) => { c.push([el, b[ind]]) }); console.log(c)
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.