【问题标题】:Efficiently merge two arrays by distribute values evenly通过均匀分布值有效地合并两个数组
【发布时间】:2020-07-14 05:08:55
【问题描述】:

我已经看到许多问题/答案主题通过交替值合并两个数组。他们是这样工作的:

let array1 = ["a", "b", "c", "d"];
let array2 = [1, 2];

let outcome = ["a",1 ,"b", 2, "c", "d"] 

但我希望输出更高效,根据数组大小均匀分布值。

expected outcome = ["a","b", 1, "c", "d", 2] 

其他场景

let array2 = [1];
expected outcome = ["a","b", 1, "c", "d"] 

实现这种合并的最佳方式应该是什么?

【问题讨论】:

  • 第一种情况和第二种情况不一致。为什么第一个以2 结尾而不是["a", 1, "b", 2, "c", "d"] 之类的结尾
  • 对于数组[a, b, c, d, e, f][1, 2],是变成[a, b, c, 1, d, e, f, 2]还是[a, b, 1, c, d, 2, e, f]
  • @adiga 这就是问题所在。我希望值被均匀地合并。你说为什么不 ["a", 1, "b", 2, "c", "d"],因为值 1 和 2 立即与第一个数组一个接一个地合并,还有更多元素留在后面“光盘”。它应该根据两个数组大小之间的比例均匀放置。
  • 第二条评论呢?会变成[a, b, c, 1, d, e, f, 2] 还是[a, b, 1, c, d, 2, e, f],为什么?
  • @adiga 回答您的问题。对于数组 [a, b, c, d, e, f] 和 [1, 2],它是变成 [a, b, c, 1, d, e, f, 2] 还是 [a, b, 1 , c, d, 2, e, f]?我不介意结果 [a, b, c, 1, d, e, f, 2] 或 [a, b, 1, c, d, 2, e, f] 只要值是均匀放置的跨度>

标签: javascript arrays array-merge


【解决方案1】:

求两个数组长度的比率longest.length/shortest.length,然后从最长的数组中取最短的数组。

let array1 = ["a", "b", "c", "d", "e"];
let array2 = [1, 2];

const evenDistribute = (array1, array2) => {
  const longest = array1.length > array2.length ? array1 : array2;
  const shortest = array1.length > array2.length ? array2 : array1;
  const ratio = Math.floor(longest.length / shortest.length);
  const results = [];
  for (let i = 0; i < shortest.length; i++) {
    for (let j = 0; j < ratio; j++) {
      results.push(longest[i * ratio + j]);
    }
    results.push(shortest[i]);
  }
  // Grab any that are left over
  for (let i = longest.length - (longest.length % shortest.length); i < longest.length; i++) {
    results.push(longest[i]);
  }
  return results;
}

console.log(evenDistribute(array1, array2));

【讨论】:

  • OP 可以编写边缘情况,将单个项目粘贴在数组中间
  • @AdrianBrand 您的回答似乎工作正常。使用不同的输入进行测试。如果只有一个元素,我不介意数组中元素的位置。
【解决方案2】:

我们的想法是找出长数组中有多少项,您必须混合短数组中的一项。下面的代码是为了演示这个概念。也许您必须针对所有边缘场景进行一些调整。

let array1 = ["a", "b", "c", "d"];
let array2 = [1, 2];


//Get the long and short arrays and calc the length factor
var [longArray, shortArray] = array1.length >= array2.length ? [array1, array2] : [array2, array1];
let lengthFactor = longArray.length / shortArray.length;


var c = 0
let smallIdx = 0;
let result = longArray.flatMap(item => {

  c++;
  
  if (c % lengthFactor === 0) {
    return [item, shortArray[smallIdx++]]
  }
  else
    return [item];    
})


console.log(result);

【讨论】:

  • 查看 OP 的评论,似乎无法准确满足样本,它们只是为了提供提示。所以,我相信,OP 获得了实现背后的想法,而不是确切的代码。 -谢谢
【解决方案3】:

您可以获得分布的间隔。然后循环遍历第二个数组,使用splice更新第一个数组的具体索引。

function distribute(original, replace) {
  const interval = Math.ceil(original.length / (replace.length + 1));
  replace.forEach((r, i) => original.splice(interval * (i + 1) + i, 0, r))
  console.log(...original)
}

distribute(["a", "b", "c", "d"], [1])
distribute(["a", "b", "c", "d"], [1, 2])
distribute(["a", "b", "c", "d"], [1, 2, 3])
distribute(["a", "b", "c", "d", "e", "f"], [1, 2])
distribute(["a", "b", "c", "d", "e", "f"], [1, 2, 3])

【讨论】:

    【解决方案4】:

    let array1 = ['a', 'b', 'c', 'd', 'e'];
    let array2 = [1, 2];
    
    function merge(arr1, arr2) {
        let newArr1 = JSON.parse(JSON.stringify(arr1));
        let newArr2 = JSON.parse(JSON.stringify(arr2));
        [newArr1, newArr2] = newArr1.length >= newArr2.length ? [newArr1, newArr2] : [newArr2, newArr1];
        const interval = newArr1.length / newArr2.length;
        newArr2.map((item, index) => {
            newArr1.splice(interval * (index + 1), 0, item);
        })
        return newArr1;
    }
    console.log(merge(array1, array2));

    【讨论】:

      猜你喜欢
      • 2013-06-25
      • 2020-01-15
      • 2020-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多