以“蛇”顺序合并两个数组[关闭]

问题描述 投票:2回答:5

我对此任务的解决方案感到困惑。我有两个数组:

const arr1 = [ 1,   2,   3,   4, 5, 6, 7, 8];
const arr2 = ['a', 'b', 'c', 'd'];

合并这些数组后我想要得到什么:

[1, 'a', 'b', 2, 3, 'c', 'd', 4, 5, 6, 7, 8];

从图形上看,它看起来像一条蛇

当第一阵列的长度短于第二阵列的长度时,它也必须工作。例如,我有两个数组:

const arr1 = [ 1,   2,   3,   4];
const arr2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

我希望在合并之后得到:

[1, 'a', 'b', 2, 3, 'c', 'd', 4, 'e', 'f', 'g'];

javascript arrays
5个回答
1
投票

function reorderArrays(array1, array2){
  let newArray = [];
  
  while(array1.length || array2.length) {
      array1.length && newArray.push(array1.shift());
      array2.length && newArray.push(array2.shift());
      array2.length && newArray.push(array2.shift());
      array1.length && newArray.push(array1.shift());
  }
  return newArray;
}

console.log(reorderArrays([1, 2, 3, 4, 5, 6, 7, 8], ['a', 'b', 'c', 'd']));
console.log(reorderArrays([ 1,   2,   3,   4], ['a', 'b', 'c', 'd', 'e', 'f', 'g']));

有优化的空间(例如,如果!一个数组的长度,只需将其他数组的其余部分推送到新数组)

此解决方案适用于未定义的边缘情况。


1
投票

这是一个简短且不可改变的方法:

const snake = (a, b) => Array.from( // create an array
    { length: Math.max(a.length, b.length) }, // as long as the longest of a and b
    (_, i) => i % 2 ? [b[i], a[i]] : [a[i], b[i]] // fill it with alternating pairs from a and b
  ).flat().filter(x => x !== undefined); // then flatten the pairs and remove undefined entries

console.log(...snake([1, 2, 3, 4, 5, 6, 7, 8], ['a', 'b', 'c', 'd']));
console.log(...snake([1, 2, 3, 4], ['a', 'b', 'c', 'd', 'e', 'f', 'g']));
console.log(...snake([1, 2, 4, 5], []));
console.log(...snake([], ['a', 'b', 'c', 'd']));

步骤是:

  1. 使用Array.from()创建一个数组,只要你的最长数组
  2. 用你的第一个阵列填充它,如果它更短,其余的将用undefined填充
  3. 使用Array.from()的第二个参数或使用map()将条目转换为从两个数组中取出的对,通过检查索引是偶数还是奇数来交替对的顺序
  4. 使用Array.flat()展平结果
  5. 使用undefined过滤掉Array.filter()

0
投票

这是使用flatMap的一个解决方案:

const merge = (arr1, arr2) => {
  return arr1.flatMap((x, i) => {
    const items = [x];
    if (i % 2 === 0) {
      if (i < arr2.length) {
        items.push(arr2[i]);
      }
      if (i + 1 < arr2.length) {
        items.push(arr2[i + 1]);
      }
    }
    if (i + 1 === arr1.length) {
      items.push(...arr2.slice(i + 1));
    }
    return items;
  });
}

console.log(merge([1, 2, 3, 4, 5, 6, 7, 8], ['a', 'b', 'c', 'd']));    // [1, "a", "b", 2, 3, "c", "d", 4, 5, 6, 7, 8]

console.log(merge([1, 2, 3, 4], ['a', 'b', 'c', 'd', 'e', 'f', 'g'])); // [1, "a", "b", 2, 3, "c", "d", 4, "e", "f", "g"]

说明:

传递给flatMap的函数将返回一个元素数组,以便按顺序包含在结果数组中。通过以下方式循环遍历flatMap来确定数组:

  1. 每个元素都直接包含在结果中([x]
  2. 对于每个偶数编号的索引(i % 2 === 0),最多插入两个来自arr2.push(arr2[i]).push(arr2[i + 1]))的元素。
  3. 如果你在arr1i + 1 === arr1.length)的末尾,插入arr2.push(...arr2.slice(i + 1)))的所有剩余物品

0
投票

在这里,您可以根据对所需内容的理解采用递归方法:

表格第一个数组:取1个项目,然后是2个项目,然后是1个项目,然后是2个项目,依此类推。从第二个数组总是2项。

为了概括,该方法将接收两个额外的数组,这些数组将确定要从要合并的每个数组中获取的元素的循环:

const customMerge = (a, b, toTakeA=[1], toTakeB=[1], res=[], i=0, j=0) =>
{
    if (!a.length)
        return res.concat(b);
    else if (!b.length)
        return res.concat(a);

    return customMerge(
        a.slice(toTakeA[i]),
        b.slice(toTakeB[j]),
        toTakeA,
        toTakeB,
        res.concat(a.slice(0, toTakeA[i])).concat(b.slice(0, toTakeB[j])),
        i >= toTakeA.length - 1 ? 0 : i + 1,
        j >= toTakeB.length - 1 ? 0 : j + 1
    );
}

console.log("First OP merge: ", customMerge(
    [1, 2, 3, 4, 5, 6, 7, 8],
    ['a', 'b', 'c', 'd'],
    [1, 2],
    [2]
));

console.log("Second OP merge: ", customMerge(
    [1, 2, 3, 4],
    ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
    [1, 2],
    [2]
));

// Another custom merge.
console.log("A custom merge: ", customMerge(
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
    [1, 1, 2],
    [2, 1]
));

// Simple merge, 1 and 1.
console.log("Single 1 and 1 merge: ", customMerge(
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    ['a', 'b', 'c', 'd', 'e', 'f', 'g']
));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

该方法主要使用Array.slice()Array.concat(),以防您需要阅读有关它们的文档。


0
投票

您可以先获取偏移量和第一个数组的额外元素,然后始终从两个数组中获取两个元素。这个apporach不会改变原始数组。

function getSnaked(a, b) {
    var result = [],
        l = Math.min(a.length, b.length),
        i = 0;

    result.push(...a.slice(0, 1));
    while (i < l) {
        result.push(...b.slice(i, ++i + 1));
        result.push(...a.slice(i, ++i + 1));
    }
    result.push(...b.slice(i));
    result.push(...a.slice(i + 1));
    return result;
}

console.log(...getSnaked([1, 2, 3, 4], ['a', 'b', 'c', 'd', 'e', 'f', 'g']));
console.log(...getSnaked([1, 2, 3, 4, 5, 6, 7, 8], ['a', 'b', 'c']));
console.log(...getSnaked([1, 2, 3, 4], []));
console.log(...getSnaked([], ['a', 'b', 'c', 'd', 'e', 'f', 'g']));
© www.soinside.com 2019 - 2024. All rights reserved.