我如何在JavaScript压缩两个数组?

我有两个数组:

var a = [1, 2, 3]
var b = [a, b, c]

我想要得到的结果是:

[[1, a], [2, b], [3, c]]

看起来很简单,但我就是想不出来。

我希望结果是一个数组,其中两个数组中的每个元素都压缩在一起。

190795 次浏览
使用map方法:
var a = [1, 2, 3]
var b = ['a', 'b', 'c']


var c = a.map(function(e, i) {
return [e, b[i]];
});


console.log(c)

DEMO

长度相同的Zip数组:

使用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"]]

不同长度的Zip数组:

使用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"]]

使用Array.prototype.fill ()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"]]

Zip多个(n)数组:

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

通过利用生成器函数进行压缩

你也可以使用生成器函数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.

Zipping of all Iterables

Here a function which can be used for all Iterables (e.g. 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}`);
}

显然,也可以只使用[...Iterable]将任何Iterable转换为数组,然后使用第一个函数。

使用reduce方法:

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)

使用forEach方法:

const a = [1, 2, 3]
const b = ['a', 'b', 'c']
const c = [];
a.forEach((el, ind) => {
c.push([el, b[ind]])
});
console.log(c)

通过简单的for loop提供命令式编程的解决方案。

与方便的数组函数如map()forEach()相比,在巨大的 数据集上执行邮政编码操作时性能更好。

例子:

const a = [1, 2, 3];
const b = ['a', 'b', 'c'];
const result = [];
for (let i = 0; i < a.length; i++) {
result.push([a[i], b[i]]);
}
console.log(result);

如果你想要一个1行的更简单的解决方案,那么你可以使用像ramda这样的库,它有一个邮政编码函数。

例子:

const a = [1, 2, 3];
const b = ['a', 'b', 'c'];
const result = R.zip(a, b);
console.log(result);