在 Javascript 中合并特定索引处的 2 个数组

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

我有一个

target
数组,说:
[A, C, E, F, H]
。 我有另一个数组
toMerge
需要合并到
target
中,比如:
[B, D, G, I]
。 我还有一个整数数组,它告诉目标数组的索引,其中
toMerge
项最终将合并到,例如:
[1, 3, 6, 8]

我需要一个函数,将

toMerge
数组合并到
target
中,在
indices
数组指定的索引处,以便
target
最终看起来像

[A(0), B(1), C(2), D(3), E(4), F(5), G(6), H(7), I(8)]

我尝试使用内置的数组拼接函数来迭代索引数组并在每个索引处进行拼接(添加)。大致意思是:

for (let i = 0; i < indices.length; i++) {
    target.splice(indices[i], 0, toMerge[i]);
}

我正在寻找任何可以更高效、更优雅地完成此操作的解决方案。

如果

indices
数组是未排序或更糟 - 反向排序,事情会变得更加棘手!例如,

toMerge: [I, G, D, B]
indices: [8, 6, 3, 1]

应用上述算法后,

target
最终为:

target: [A, B, C, E, D, F, H, I, G]

解决此问题的一种方法是将

indices
数组与
toMerge
数组一起按非降序排序,以确保遵循顺序,但这会使事情进一步复杂化。

javascript arrays array-merge
2个回答
0
投票

未排序索引+绝对值

如果您正在使用未排序的索引:您必须“压缩”(需要首先

transpose
)要合并的数组及其相应的索引。一旦您对
[index, value][]
矩阵进行了排序,就可以执行有序拼接。

const transpose = (a) => a[0].map((_, i) => a.map(r => r[i]));
const sortByIndex = (a) => a.sort((x, y) => x[0] - y[0]);

const absoluteMerge = (a, toMerge, unsortedIndices) => {
  const res = [...a];
  const sorted = sortByIndex(transpose([unsortedIndices, toMerge]));
  for (let i = 0; i < sorted.length; i++) {
    res.splice(sorted[i][0], 0, sorted[i][1]);
  }
  return res;
};

const a = ['A', 'C', 'E', 'F', 'H'], b = ['I', 'G', 'D', 'B'];

const c = absoluteMerge(a, b, [8, 6, 3, 1]);

console.log(...c); // A B C D E F G H I


原始回复

如果您正在使用绝对索引(就像您一样),您可以按顺序插入项目;但如果使用相对索引,则需要反转插入。

绝对合并

const absoluteMerge = (a, b, insertionIndices) => {
  const res = [...a];
  for (let i = 0; i < insertionIndices.length; i++) {
    res.splice(insertionIndices[i], 0, b[i]);
  }
  return res;
};

const a = ['A', 'C', 'E', 'F', 'H'], b = ['B', 'D', 'G'];

const c = absoluteMerge(a, b, [1, 3, 6]);

console.log(...c); // A B C D E F G H

相对合并

const relativeMerge = (a, b, insertionIndices) => {
  const res = [...a];
  for (let i = insertionIndices.length - 1; i >= 0; i--) {
    res.splice(insertionIndices[i], 0, b[i]);
  }
  return res;
};

const a = ['A', 'C', 'E', 'F', 'H'], b = ['B', 'D', 'G'];

const c = relativeMerge(a, b, [1, 2, 4]);

console.log(...c); // A B C D E F G H


0
投票

考虑排序、逆序和未排序列表的可能性

toMerge
,首先我们需要将
toMerge
indices
列表合并并排序,然后我们可以将这些值与
target
列表合并,例如:

const mergeArraysByIndex = (target, toMerge, indices) => {
  // Create an array of objects with keys and values
  const toMergeWithIndex = toMerge.map((key, index) => ({key, value: indices[index]}));

  // Sort the array of objects by value
  toMergeWithIndex.sort((a, b) => a.value - b.value);

  // Create a final object with sorted keys and values
  const resultObject = {};
  toMergeWithIndex.forEach(item => {
    resultObject[item.key] = item.value;
  });

  //Merge the arrays together
  return Object.values(resultObject).reduce((acc, index, i) => {
    acc.splice(index, 0, Object.keys(resultObject)[i]);
    return acc;
  }, [...target])
}

//First example (sorted!)
console.log(mergeArraysByIndex(['A', 'C', 'E', 'F', 'H'], ['B', 'D', 'G'], [1, 3, 6]));

//Second example (reverse-sorted!)
console.log(mergeArraysByIndex(['A', 'C', 'E', 'F', 'H'], ['I', 'G', 'D', 'B'], [8, 6, 3, 1]));

//Third example (unsorted!)
console.log(mergeArraysByIndex(['A', 'C', 'E', 'F', 'H'], ['D', 'I', 'G', 'B'], [3, 8, 6, 1]));

或者以恢复的方式:

const mergeArraysByIndex = (target, toMerge, indices) => {
  return indices
    .map((index, i) => ({ key: toMerge[i], index }))
    .sort((a, b) => a.index - b.index)
    .reduce((acc, { key, index }) => {
      acc.splice(index, 0, key);
      return acc;
    }, [...target]);
};

//First example (sorted!)
console.log(mergeArraysByIndex(['A', 'C', 'E', 'F', 'H'], ['B', 'D', 'G'], [1, 3, 6]));

//Second example (reverse-sorted!)
console.log(mergeArraysByIndex(['A', 'C', 'E', 'F', 'H'], ['I', 'G', 'D', 'B'], [8, 6, 3, 1]));

//Third example (unsorted!)
console.log(mergeArraysByIndex(['A', 'C', 'E', 'F', 'H'], ['D', 'I', 'G', 'B'], [3, 8, 6, 1]));

© www.soinside.com 2019 - 2024. All rights reserved.