【问题标题】:Splitting an array of numbers into sorted groups将数字数组拆分为已排序的组
【发布时间】:2019-12-02 22:27:26
【问题描述】:

我有一个数组,其绝对值保证小于 10。

我现在正在做的是使用Array.prototype.sort()按升序对其进行排序:

myArray.sort(function (a, b) {
    return a - b;
})

但任务是按组排序而不重复,换句话说,有一个数组

a = [1,2,2,3,1,4,4,2,9,8]

我需要得到输出

b = [1,2,3,4,8,9,1,2,4]

我有一个想法在函数表达式中使用Array.prototype.push() 将重复的数字添加到数组的末尾。但是由于明显的原因,由于存在范围,我不能这样做:

myArray.sort(function (a, b) {
    if(a === b){
        this.myArray.push(b);
        return 0;
    }
    else{
        return a - b;
    }
})

是否可以使用Array.prototype.sort() 来实现我的想法,或者编写一个单独的函数是否更容易、更正确?

【问题讨论】:

  • @MarkMeyer 另一个例子:a = [1,1,2,2,3,3,4,4,5,5] 期望输出:b = [1,2,3,4,5,1,2,3,4,5]
  • 对不起@Nikita——我看错了问题,没有看到你发布的例子。

标签: javascript arrays function sorting


【解决方案1】:

您可以使用sorting with map,将临时对象与同一组数组的哈希表一起使用。从中取出所用数组的长度作为分组进行排序。

排序发生在组和值上。

结果映射到已排序临时数组的索引。

var array = [1,2,2,3,1,4,4,2,9,8],
    groups = Object.create(null),
    result = array
        .map((value, index) => ({ index, value, group: groups[value] = (groups[value] || 0 ) + 1 }))
        .sort((a, b) => a.group - b.group || a.value - b.value)
        .map(({ value }) => value);

console.log(...result);

【讨论】:

  • 为什么不groups[value] = (groups[value] || 0) + 1 ?为什么不.map(({ value }) => value)
  • 另外|| a.index - b.index 是superflouos(只要没有人使用Number 对象)
【解决方案2】:

您可以创建一个group 对象,该对象将每个数字创建为键,并将该数字的数组创建为值。然后,遍历对象并将每个数字添加到输出。每次数组变空时,删除键。运行这个直到对象没有剩下的键。

const input = [1, 2, 2, 3, 1, 4, 4, 2, 9, 8],
      group = {},
      output = [];

input.forEach(n => (group[n] = group[n] || []).push(n))

while (Object.keys(group).length > 0) {
  for (const key in group) {
    output.push(group[key].pop())

    if (group[key].length === 0)
      delete group[key];
  }
}

console.log(output)

注意:对于数字键,对象的键是按升序遍历的。所以,这只适用于数组中有自然数的情况)

【讨论】:

    【解决方案3】:

    以下是您可以采取的方法 - cmets 详细说明了每个步骤的用途:

    const a = [1, 2, 2, 3, 1, 4, 4, 2, 9, 8];
    
    //Create an occurrence map
    const map = a.reduce((accum, i) => {
      if (accum[i]) {
        accum[i] += 1;
      } else {
        accum[i] = 1;
      }
    
      return accum;
    }, {});
    
    //We need to iterate the map as many times as the largest value
    const iterations = Math.max(...Object.values(map));
    
    const sorted = [];
    for (let i = 0; i < iterations; i += 1) {
      Object.entries(map).forEach(entry => {
        const [val, count] = entry;
        if (count > 0) {
          sorted.push(parseInt(val)); //Add it to our sorted array
          map[val] -= 1; //Reduce the number of occurrences in the map for this key
        }
      });
    }
    
    console.log(sorted);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 2017-09-13
      相关资源
      最近更新 更多