如何在JavaScript中压缩和解压数组?
将两个或多个数组压缩指的是将它们的元素合并为一个数组的数组。由于听起来相当模糊,让我们看一个例子:
const arrays = ['a', 'b'], [1, 2], [true, false];
const zipped = [['a', 1, true], ['b', 2, false]]
如您所见,此示例中的第一个数组包含原始数组的所有第一个元素,第二个数组包含所有第二个元素,依此类推。
压缩数组
压缩需要创建一个具有参数中最长数组的长度的数组。我们可以使用Math.max()
和展开运算符(...
)来获取数组中最长的子数组,并使用Array.from()
创建一个适当长度的数组。
然后,使用Array.prototype.map()
,我们可以为新数组的每个元素创建一个数组。每个数组的长度是传递给函数的参数数量。使用Array.from()
中的最后一个参数,我们可以遍历原始数组的索引并创建一个包含该索引处元素的新数组。
const zip = (...arrays) => {
const maxLength = Math.max(...arrays.map(x => x.length));
return Array.from({ length: maxLength }).map((_, i) => {
return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]);
});
};
zip(['a', 'b'], [1, 2], [true, false]); // [['a', 1, true], ['b', 2, false]]
zip(['a'], [1, 2], [true, false]); // [['a', 1, true], [undefined, 2, false]]
解压数组
解压缩的逆过程是解压,它将数组的数组转换回单独的数组。我们可以使用Math.max()
和展开运算符(...
)来获取数组中的最长子数组,并使用Array.from()
创建一个适当长度的数组。
然后,使用Array.prototype.reduce()
和Array.prototype.forEach()
,我们可以通过将每个值推送到相同索引处的数组来将分组的值映射到单独的数组。
const unzip = arr =>
arr.reduce(
(acc, val) => (val.forEach((v, i) => acc[i].push(v)), acc),
Array.from({
length: Math.max(...arr.map(x => x.length))
}).map(x => [])
);
unzip([['a', 1, true], ['b', 2, false]]); // [['a', 'b'], [1, 2], [true, false]]
unzip([['a', 1, true], ['b', 2]]); // [['a', 'b'], [1, 2], [true]]
将数组压缩为对象
如果要将数组压缩为对象,可以使用与压缩数组相似的技术。唯一的区别是您需要使用Array.prototype.reduce()
将键值对分配给对象。
const zipObject = (props, values) =>
props.reduce((obj, prop, index) => ((obj[prop] = values[index]), obj), {});
zipObject(['a', 'b', 'c'], [1, 2]); // {a: 1, b: 2, c: undefined}
zipObject(['a', 'b'], [1, 2, 3]); // {a: 1, b: 2}
将对象解压为数组
将对象解压为一对数组非常简单。您可以使用Object.keys()
和Object.values()
将对象的键和值作为数组获取。
const unzipObject = obj => [
Object.keys(obj),
Object.values(obj)
];
unzipObject({a: 1, b: 2, c: 3}); // [['a', 'b', 'c'], [1, 2, 3]]
unzipObject({a: 1, b: 2}); // [['a', 'b'], [1, 2]]
const unzipObject = obj => [
Object.keys(obj),
Object.values(obj)
];
unzipObject({a: 1, b: 2, c: 3}); // [['a', 'b', 'c'], [1, 2, 3]]
unzipObject({a: 1, b: 2}); // [['a', 'b'], [1, 2]]