【问题标题】:JS - Get top 5 max elements from arrayJS - 从数组中获取前 5 个最大元素
【发布时间】:2020-09-06 15:07:16
【问题描述】:

如何从整数数组中获取前 5 个最大元素,而整数数组又是 js 对象的属性。 感谢您的帮助。

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    ES6 中的解决方案:

    values = [1,65,8,98,689,12,33,2,3,789];
    var topValues = values.sort((a,b) => b-a).slice(0,5);
    console.log(topValues); // [789,689,98,65,33]
    

    还有很多其他的,请问您是否需要更多

    【讨论】:

    • (a,b) => a>b - 不是真的。
    • [2, 6, 8, 1].sort((a, b) => b>a) [2, 6, 8 1] 不正确 [2, 6, 8, 1]。 sort((a, b) => b - a) [8, 6, 2, 1] 正确,排序函数应该是(a,b) => b - a
    【解决方案2】:

    [2, 6, 8, 1, 10, 11].sort((a, b) => b - a).slice(0,5)

    [11、10、8、6、2]

    【讨论】:

      【解决方案3】:

      虽然@Kevin 和@Cody 的上述方法是正确的,但它也会更改可能影响您的代码的原始数组。我建议先复制数组,然后执行排序。由于您的数组仅包含整数,因此我们可以对其进行浅拷贝。为此,您可以使用扩展运算符:

      values = [1,65,8,98,689,12,33,2,3,789];
      var topValues = [...values].sort((a,b) => b-a).slice(0,5); 
      // [...values] will create shallow copy
      console.log(topValues); // [789, 689, 98, 65, 33]
      

      【讨论】:

        【解决方案4】:

        其他答案中已经提到的“代码行数”高效代码,这里是更好的运行时和内存效率的算法:

        如果您可以就地修改输入数组:递归地对其进行分区,直到您的枢轴恰好位于第 5 位。这种方法具有线性时间平均复杂度。

        另一种方法(不需要修改输入数组):

        使用最大堆树,遍历输入数组中的所有元素,每一步将元素插入堆树,如果包含超过 5 个元素,则从堆中删除最小元素。该算法的运行时间为 N*log(5),因此与输入数组大小相比也是线性的

        【讨论】:

          【解决方案5】:

          除非假设数组没有重复元素,否则这个问题是模棱两可的。

          // Case 1: unique values
          values = [1, 65, 8, 98, 689, 12, 33, 2, 3, 789];
          var topValues = [...values].sort((a, b) => b - a).slice(0, 5);
          
          console.log(topValues);
          // [789, 689, 98, 65, 33]
          
          // Case 2: non-unique values
          values = [1, 65, 65, 8, 98, 689, 12, 33, 2, 3, 789];
          var topValues = [...values].sort((a, b) => b - a).slice(0, 5);
          
          console.log(topValues);
          // [789, 689, 98, 65, 65]

          如果出现重复,最高值是多少?如果您对数组 [1, 65, 65, 8, 98, 689, 12, 33, 2, 3, 789] 进行排序并取前 5 个值,则会得到

          [789, 689, 98, 65, 65]
          

          要获得前 5 个 唯一 值,请使用 filterindexOf 在切片前选择重复值:

          values = [1, 65, 65, 8, 98, 689, 12, 33, 2, 3, 789];
          var topValues = 
            [...values].sort((a, b) => b - a)
                       .filter((v,i,self) => self.indexOf(v) === i)
                       .slice(0, 5);
          
          console.log(topValues);
          // [789, 689, 98, 65, 33]

          或者,在支持 ES6 的浏览器上 Set:

          values = [1, 65, 65, 8, 98, 689, 12, 33, 2, 3, 789];
          var topValues = 
            [...new Set(values)].sort((a, b) => b - a)  
                                .slice(0, 5);
          
          console.log(topValues);
          // [789, 689, 98, 65, 33]

          the suggestion in this other answer 之后,我将sort 应用于数组的副本。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-31
            • 2022-07-27
            • 1970-01-01
            • 1970-01-01
            • 2011-01-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多