不使用.concat按索引合并JavaScript数组的实现方案
按索引一一对应合并为扁平数组的解决方案
我懂你的需求啦——你要的不是把两个数组按索引配对成嵌套的二维数组,而是要把每一组对应位置的元素依次平铺进同一个数组里,对吧?
先说说你现有代码的问题:你的zip方法返回的是嵌套数组,每个索引对应的两个元素被打包成了子数组,所以输出是[["golf","player1"],["hockey","player2"],["tennis","player3"]],和你想要的扁平结构不一样。
下面给你几种可行的解决方法:
方法一:修改原型方法直接生成扁平数组
如果你想继续用扩展Array.prototype的方式,可以把方法改成用reduce来逐个构建扁平数组:
let arr1 = ['golf', 'hockey', 'tennis']; let arr2 = ['player1', 'player2', 'player3']; Array.prototype.zipFlatten = function(arr) { return this.reduce((finalArr, currentItem, index) => { // 依次把当前数组元素和另一个数组的对应元素push进结果数组 finalArr.push(currentItem, arr[index]); return finalArr; }, []); // 初始值是空数组 }; const arr3 = arr1.zipFlatten(arr2); console.log(arr3); // 输出: ["golf", "player1", "hockey", "player2", "tennis", "player3"]
方法二:用独立函数实现(更推荐,避免污染原生原型)
很多开发者不推荐随意扩展原生对象的原型,所以可以写一个独立的工具函数,还能处理两个数组长度不一致的情况:
const zipAndFlatten = (arrA, arrB) => { const mergedArr = []; // 取两个数组中较长的长度,避免遗漏元素 const maxLength = Math.max(arrA.length, arrB.length); for (let i = 0; i < maxLength; i++) { // 只在索引存在时添加元素,避免undefined if (i < arrA.length) mergedArr.push(arrA[i]); if (i < arrB.length) mergedArr.push(arrB[i]); } return mergedArr; }; // 测试用例 let arr1 = ['golf', 'hockey', 'tennis']; let arr2 = ['player1', 'player2', 'player3']; const arr3 = zipAndFlatten(arr1, arr2); console.log(arr3); // 符合期望的扁平数组 // 测试长度不一致的情况 let arr4 = ['a', 'b']; let arr5 = ['x', 'y', 'z']; console.log(zipAndFlatten(arr4, arr5)); // 输出: ["a", "x", "b", "y", "z"]
方法三:基于你的原有代码快速改造
如果你不想大改现有代码,也可以在原有zip方法的结果上调用flat()方法,直接把嵌套数组平铺:
let arr1 = ['golf', 'hockey', 'tennis']; let arr2 = ['player1', 'player2', 'player3']; Array.prototype.zip = function (arr) { return this.map(function (e, i) { return [ e, arr[i]]; }) }; const arr3 = arr1.zip(arr2).flat(); // 新增.flat() console.log(arr3); // 同样能得到期望的扁平数组
内容的提问来源于stack exchange,提问作者Mark Hayden
相关产品推荐
相关产品推荐

