【问题标题】:JavaScript objects array filter by minimum value of an attributeJavaScript对象数组按属性的最小值过滤
【发布时间】:2018-11-01 08:47:53
【问题描述】:

我需要通过“rest”属性的最小值过滤这个对象数组。这是一种方法。还有其他方法吗?

'data' 变量是链式函数的结果。有没有其他方法可以做到这一点,而无需在 Math.min() 函数中再次调用“数据”变量。

let data = 
[ { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } ]

let result = data.filter(e=> e.rest === Math.min(...data.map(f=>f.rest) ) );
console.log(result);

// result is
//[ { size: 5, qty: 2, rest: 0 },
//  { size: 2, qty: 5, rest: 0 },
//  { size: 1, qty: 10, rest: 0 }]

【问题讨论】:

    标签: javascript arrays math ecmascript-6


    【解决方案1】:

    最简单的方法是将 min 函数拉出过滤器,如下所示:

    let min = Math.min(...data.map(item => item.rest))
    

    这更有效,因为我们不再循环数据以找到过滤器每次迭代的最小值。

    我们现在有 n * 2 遍而不是 n^2 遍。 (n 是数据集的大小,在本例中为 5)

    下面的完整示例:

       let data = [ 
         { size: 5, qty: 2, rest: 0 },
         { size: 2, qty: 5, rest: 0 },
         { size: 1, qty: 10, rest: 0 },
         { size: 3, qty: 3, rest: 1 },
         { size: 4, qty: 2, rest: 2 } 
       ]
    
      let min = Math.min(...data.map(item => item.rest))
      let result = data.filter(item => item.rest === min)
      console.log(result)
    

    希望这会有所帮助!

    劳埃德

    【讨论】:

    • 谢谢。是的,我错过了那个问题。没有其他方法可以通过方法链接来做到这一点吗?
    • 您将始终需要将其余值与最小变量或预定义阈值进行比较,您的初始帖子是方法链接的示例。
    • 谢谢。 :)
    【解决方案2】:

    我。最简单/最好的解决方案是@CertainPerformance 为您提供的解决方案。

    只是想添加另一个具有线性运行时的解决方案(真正只在数组上迭代一次)

    let data = [
      { size: 5, qty: 2, rest: 0 },
      { size: 2, qty: 5, rest: 0 },
      { size: 1, qty: 10, rest: 0 },
      { size: 3, qty: 3, rest: 1 },
      { size: 4, qty: 2, rest: 2 } 
    ];
    
    let result = data.reduce((result, item) => {
      let minRest = result.length? result[0].rest: item.rest;
    
      if (item.rest < minRest) {
        minRest = item.rest;
        result.length = 0;
      }
    
      if (item.rest === minRest) {
        result.push(item);
      }
    
      return result;
    }, []);
    
    console.log(result);

    @mathieux51 让我了解了如何在方法链中执行此操作,但可读性/清晰度/意图不如其他方法:

    let data = [
      { size: 5, qty: 2, rest: 0 },
      { size: 2, qty: 5, rest: 0 },
      { size: 1, qty: 10, rest: 0 },
      { size: 3, qty: 3, rest: 1 },
      { size: 4, qty: 2, rest: 2 } 
    ];
    
    let result = data.sort((a, b) => a.rest - b.rest)
                     .filter((item, index, array) => item.rest === array[0].rest);
    
    console.log(result);

    【讨论】:

    • 非常感谢。最后一个是我要找的那个。
    • 虽然排序有O(N log N)的复杂性
    【解决方案3】:

    data.map 里面的data.filterO(N^2);对于O(N) 解决方案,提前遍历data 以计算最小值,然后通过该最小值计算filter

    let data = 
    [ { size: 5, qty: 2, rest: 0 },
      { size: 2, qty: 5, rest: 0 },
      { size: 1, qty: 10, rest: 0 },
      { size: 3, qty: 3, rest: 1 },
      { size: 4, qty: 2, rest: 2 } ];
    const minRest = Math.min(...data.map(({ rest }) => rest));
    
    let result = data.filter(({ rest }) => rest === minRest);
    console.log(result);

    【讨论】:

    • 谢谢。我错过了。但这不是我要找的。有没有其他方法不声明变量。
    • 很遗憾,没有,如果您想要O(N) 的性能,您将必须声明或使用另一个变量。 (如果您不想将其暴露给外部范围,请随意将其放入 IIFE)
    【解决方案4】:

    听起来您想对列表进行排序。我会这样做:

    const result = data.sort((a, b) => a.rest - b.rest)
    

    【讨论】:

    • 按最小rest 值排序和过滤。
    • 只是排序也应该可以。获取第一个或最后一个项目,即 min 和 max
    【解决方案5】:

    获取最小值或最大值 由于没有人提到这种方法,我将在这里更新它。

    myArray.sort(function (a, b) {
    return a.rest - b.rest
    })
    
    var min = myArray[0],
    max = myArray[myArray.length - 1]
    

    它具有良好的可读性/清晰度/意图。

    【讨论】:

      猜你喜欢
      • 2022-08-18
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 2017-03-19
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 2019-05-29
      相关资源
      最近更新 更多