【问题标题】:Fast way to get the min/max values among properties of object获取对象属性中的最小值/最大值的快速方法
【发布时间】:2012-06-23 23:11:56
【问题描述】:

我在 javascript 中有一个像这样的对象:

{ "a":4, "b":0.5 , "c":0.35, "d":5 }

有没有一种快速的方法来获得属性中的最小值和最大值,而不必遍历它们?因为我拥有的对象很大,我需要每两秒获取一次最小值/最大值。 (对象的值不断变化)。

【问题讨论】:

  • @Oleg:好吧,仅考虑到这一点,它很可能是 JSON。 Youssef:将 JSON 解析为一个对象并迭代其属性。
  • @OlegV.Volkov 我正在使用 JSON.parse() 不应该是 Json 吗?
  • @Youssef 解析前是 JSON(这是一个 String 值)。解析后是一个Object值。
  • JSON 是对象的字符串表示法。当您将 JSON 解析为对象时,它不再是 JSON 格式
  • 我冒昧地修复了您问题中的 JSON -> 对象,因为 cmets 确认这是您的意思。

标签: javascript jquery


【解决方案1】:

更新:现代版(ES6+)

let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };

let arr = Object.values(obj);
let min = Math.min(...arr);
let max = Math.max(...arr);

console.log( `Min value: ${min}, max value: ${max}` );

原答案:

试试这个:

let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });

然后:

var min = Math.min.apply( null, arr );
var max = Math.max.apply( null, arr );

现场演示: http://jsfiddle.net/7GCu7/1/

【讨论】:

  • 也可以max = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
  • 现在也可以这样做:Math.max(...arr);
  • @cmac 我已经添加了 ES6 版本。
  • @ŠimeVidas - Math.min 和 max 函数上的 3 个点代表什么?谢谢
【解决方案2】:

如果不遍历所有 n 元素(如果从 1 到 n-1,你怎么知道元素是否 n 不大于(或小于)当前的最大值/最小值)?

您提到值每隔几秒就会改变一次。如果您确切知道哪些值发生了变化,您可以从以前的最大值/最小值开始,只与新的值进行比较,但即使在这种情况下,如果修改的值之一是旧的最大值/最小值,您可以需要再次循环它们。

另一种选择 - 再次,仅当更改的值的数量很小时 - 将值存储在诸如树或堆之类的结构中,并且当新值到达时,您将插入(或更新)他们适当地。但是根据您的问题,您是否可以做到这一点尚不清楚。

如果您想在遍历所有元素时获取给定列表的最大/最小元素,那么您可以使用下面的 sn-p 之类的东西,但如果不遍历所有元素,您将无法做到这一点

var list = { "a":4, "b":0.5 , "c":0.35, "d":5 };
var keys = Object.keys(list);
var min = list[keys[0]]; // ignoring case of empty list for conciseness
var max = list[keys[0]];
var i;

for (i = 1; i < keys.length; i++) {
    var value = list[keys[i]];
    if (value < min) min = value;
    if (value > max) max = value;
}

【讨论】:

  • 这里没有描述如何获取对象属性的最小值/最大值。
  • 您正在迭代一个对象,而不是一个列表。 minmax 未定义。您的意思是改用for in 循环吗?
【解决方案3】:

你可以试试:

const obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
const max = Math.max.apply(null, Object.values(obj));
console.log(max) // 5

【讨论】:

    【解决方案4】:

    minmax 无论如何都必须遍历输入数组 - 否则他们将如何找到最大或最小元素?

    所以只需一个快速的for..in 循环就可以正常工作。

    var min = Infinity, max = -Infinity, x;
    for( x in input) {
        if( input[x] < min) min = input[x];
        if( input[x] > max) max = input[x];
    }
    

    【讨论】:

    • 这非常适合 IE7/8。干杯@Niet the Dark Absol
    • min 和 max 循环遍历数组来获取它们的值并不一定是真的。他们对数组进行快速排序并根据该结果选择最小值和最大值更为可行
    • @goonerify 最快的排序是O(n log n),它本质上比只扫描一次的O(n) 慢...
    【解决方案5】:
    // 1. iterate through object values and get them
    // 2. sort that array of values ascending or descending and take first, 
    //    which is min or max accordingly
    let obj = { 'a': 4, 'b': 0.5, 'c': 0.35, 'd': 5 }
    let min = Object.values(obj).sort((prev, next) => prev - next)[0] // 0.35
    let max = Object.values(obj).sort((prev, next) => next - prev)[0] // 5
    

    【讨论】:

    • 已添加说明。
    【解决方案6】:

    你也可以试试Object.values

    const points = { Neel: 100, Veer: 89, Shubham: 78, Vikash: 67 };
    
    const vals = Object.values(points);
    const max = Math.max(...vals);
    const min = Math.min(...vals);
    console.log(max);
    console.log(min);

    【讨论】:

      【解决方案7】:

      使用lodash library你可以写得更短

      _({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
      

      【讨论】:

        【解决方案8】:

        这是一种解决方案,它也允许您返回密钥并且只执行一个循环。它对对象的条目进行排序(按 val),然后返回第一个和最后一个。

        此外,它返回排序后的对象,它可以替换现有对象,因此未来的排序会更快,因为它已经是半排序的 = 比 O(n) 更好。 请务必注意,对象在 ES6 中保持其顺序。

        const maxMinVal = (obj) => {
          const sortedEntriesByVal = Object.entries(obj).sort(([, v1], [, v2]) => v1 - v2);
        
          return {
            min: sortedEntriesByVal[0],
            max: sortedEntriesByVal[sortedEntriesByVal.length - 1],
            sortedObjByVal: sortedEntriesByVal.reduce((r, [k, v]) => ({ ...r, [k]: v }), {}),
          };
        };
        
        const obj = {
          a: 4, b: 0.5, c: 0.35, d: 5
        };
        
        console.log(maxMinVal(obj));

        【讨论】:

        • 谢谢!我试图弄清楚如何获得最大值,同时仍然保留与价值相匹配的关键。这有帮助! :)
        【解决方案9】:

        对于不同深度的嵌套结构,即{node: {leaf: 4}, leaf: 1},这将起作用(使用lodash或下划线):

        function getMaxValue(d){
            if(typeof d === "number") {
                return d;
            } else if(typeof d === "object") {
                return _.max(_.map(_.keys(d), function(key) {
                    return getMaxValue(d[key]);
                }));
            } else {
                return false;
            }
        }
        

        【讨论】:

          【解决方案10】:
          var newObj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
          var maxValue = Math.max(...Object.values(newObj))
          var minValue = Math.min(...Object.values(newObj))
          

          【讨论】:

          • 在回答一个老问题时,如果您包含一些上下文来解释您的答案如何提供帮助,那么您的答案对其他 StackOverflow 用户会更有用,特别是对于已经有公认答案的问题。请参阅:How do I write a good answer
          【解决方案11】:

          您可以使用reduce() 函数。

          例子:

          let obj = { "a": 4, "b": 0.5, "c": 0.35, "d": 5 }
          
          let max = Object.entries(obj).reduce((max, entry) => entry[1] >= max[1] ? entry : max, [0, -Infinity])
          let min = Object.entries(obj).reduce((min, entry) => entry[1] <= min[1] ? entry : min, [0, +Infinity])
          
          console.log(max) // ["d", 5]
          console.log(min) // ["c", 0.35]
          

          【讨论】:

            【解决方案12】:
            // Sorted
            let Sorted = Object.entries({ "a":4, "b":0.5 , "c":0.35, "d":5 }).sort((prev, next) => prev[1] - next[1])
            >> [ [ 'c', 0.35 ], [ 'b', 0.5 ], [ 'a', 4 ], [ 'd', 5 ] ]
            
            
            //Min:
            Sorted.shift()
            >> [ 'c', 0.35 ]
            
            // Max:
            Sorted.pop()
            >> [ 'd', 5 ]
            

            【讨论】:

              【解决方案13】:

              这对我有用:

              var object = { a: 4, b: 0.5 , c: 0.35, d: 5 };
              // Take all value from the object into list
              var valueList = $.map(object,function(v){
                   return v;
              });
              var max = valueList.reduce(function(a, b) { return Math.max(a, b); });
              var min = valueList.reduce(function(a, b) { return Math.min(a, b); });
              

              【讨论】:

                【解决方案14】:
                   obj.prototype.getMaxinObjArr = function (arr,propName) {
                        var _arr = arr.map(obj => obj[propName]);
                        return Math.max(..._arr);
                    }
                

                【讨论】:

                  【解决方案15】:

                  获取最大值和最小值的键

                  var list = { "a":4, "b":0.5 , "c":0.35, "d":5 };
                  var keys = Object.keys(list);
                  var min = keys[0]; // ignoring case of empty list for conciseness
                  var max = keys[0];
                  var i;
                  
                  for (i = 1; i < keys.length; i++) {
                      var value = keys[i];
                      if (list[value] < list[min]) min = value;
                      if (list[value] > list[max]) max = value;
                  }
                  
                  console.log(min, '-----', max)

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-09-20
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多