在 JavaScript 中交错多个数组

3
我们有一个数组的数组,想要将它们交错成一个单一的数组: 例如:
masterArray = [[1, 2, 3], ['c', 'd', 'e']] => [1, 'c', 2, 'd', 3, 'e'],
如果内部数组长度不相等,则将它填充到最长的内部数组的长度。
例如: [1, 2, 3], [4, 5]) => [1, 4, 2, 5, 3, null]
我已经满足了两个数组的情况,但如果是更多的情况,我很难形成处理多于两个的策略。
例如: [1, 2, 3], [4, 5, 6], [7, 8, 9] => [1, 4, 7, 2, 5, 8, 3, 6, 9]
function interleave(...masterArray) {
  let rtnArray = [];
  let longestArrayPosition = getLongestArray(masterArray);
  let longestInnerArrayLength = masterArray[longestArrayPosition].length; 
  padAllArraysToSameLength(masterArray, longestInnerArrayLength); //pad uneven length arrays
  
  masterArray[0].forEach((firstArrayNum, index) => {
    const secondArrayNum = masterArray[1][index];
    rtnArray.push(firstArrayNum);
    rtnArray.push(secondArrayNum);
  });

  return rtnArray;
}

function getLongestArray(masterArray) {
  return masterArray
    .map(a=>a.length)
    .indexOf(Math.max(...masterArray.map(a=>a.length)));
}

function padAllArraysToSameLength(masterArray, maxLength) {
  return masterArray.forEach(arr => {
    if (arr != maxLength) {
      while(arr.length != maxLength) {
        arr.push(null);
      }
    }
  })
}
2个回答

4
使用Array.from()方法对数组进行转置(行变列,列变行),并用null填充缺失的位置。使用Array.flat()方法将转置后的数组展开为一维数组:

const fn = arr => Array.from({ 
    length: Math.max(...arr.map(o => o.length)), // find the maximum length
  },
  (_, i) => arr.map(r => r[i] ?? null) // create a new row from all items in same column or substitute with null
).flat() // flatten the results

const arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

const result = fn(arr)

console.log(result)


下划线和双问号是什么? - hello world
1
下划线是第一个参数(值)的占位符,在这种情况下,它始终为undefined,并且不需要。??被称为Nullish 合并运算符,如果左侧为nullundefined(在当前数组上索引不存在的情况),它将返回右侧的值(在本例中为null)。这使我们能够用null替换undefined,但不能替换0。 - Ori Drori
1
一个聪明/有创意的解决方案!很好地运用了函数式编程风格,只使用了常量。 - wide_eyed_pupil

1

您可以使用两个嵌套的forEach语句对任意数量的数组执行此操作:

let arr1 = [[1,2,3],[4,5]]
let arr2 = [[1,2,3], [4,5,6], [7,8,9]]
let arr3 = [[1,2,3,4], [4,5,6], [7,8,9], [10,11,12]]

function interLeaveArrays(mainArr){
  let maxLen = Math.max(...mainArr.map(arr => arr.length))
  mainArr.forEach(arr => {
    let lenDiff = maxLen - arr.length
    for(let i=lenDiff; i>0; i--){
      arr.push(null)
    }
  })
  
  let newArr = []
  mainArr.forEach((arr, idx1) => {
    arr.forEach((el, idx2) => {
      newArr[idx2 * mainArr.length + idx1] = el
    })
  })
  return newArr
}

console.log(interLeaveArrays(arr1))
console.log(interLeaveArrays(arr2))
console.log(interLeaveArrays(arr3))


你是怎么想到在双重forEach中使用idx2 * mainArr.length + idx1作为迭代值的? - hello world
1
@helloworld 由于元素是交错的,每个元素都需要根据它在数组中的位置(idx2 * mainArr.length)以及它在自己的数组中的位置(+ idx1)进行放置。 - symlink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接