快速获取对象属性中的最小值/最大值的方法


93

我在javascript中有这样的对象:

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

是否有一种快速的方法来获取属性之间的最小值和最大值而不必遍历所有属性?因为我拥有的物体很大,所以我需要每两秒钟获取最小值/最大值。(对象的值不断变化)。


3
@Oleg:好吧,仅此而已,它很可能是JSON。Youssef:将JSON解析为一个对象并遍历其属性。
Felix Kling 2012年

@ OlegV.Volkov我正在使用JSON.parse()使其不为Json吗?
Youssef 2012年

@Youssef解析之前是JSON(这是一个字符串值)。解析后是对象值。
森那维达斯

2
JSON是对象的字符串表示法。当您将JSON解析为对象时,它不再是JSON格式
altschuler 2012年

1
我随心所欲地在您的问题中修复JSON->对象,因为评论确认这就是您的意思。
Oleg V. Volkov

Answers:


19

在没有遍历所有n个元素的情况下,通常无法找到最大值/最小值(如果从1转到n-1,如何知道元素n是否大于(或小于)n个元素?当前的最大/最小)?

您提到值每两秒钟更改一次。如果您确切知道哪个值发生了变化,则可以从以前的最大/最小值开始,仅与新的/最大值进行比较,但是即使在这种情况下,如果修改的值之一是您的旧的最大/最小值,则可以需要再次遍历它们。

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

如果要在遍历所有元素的同时获取给定列表的最大/最小元素,则可以使用下面的代码段,但是如果不遍历所有元素,将无法执行此操作

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;
}

2
这没有描述如何获取对象属性的最小/最大值。
FistOfFury

您正在遍历对象而不是列表。min并且max未定义。您是要使用for in循环吗?
tonix

1
感谢@tonix,将其修复。
carlosfigueira

138

更新:现代版本(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/


21
也可以做max = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
Levi 2014年

4
现在也可以这样做: Math.max(...arr);
cmac

1
@cmac我添加了ES6版本。
森那维达斯

@ŠimeVidas-Math.min和max函数上的三个点代表什么?谢谢
AME


12

min并且max无论如何都要遍历输入数组-他们还会如何找到最大或最小的元素?

因此,快速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];
}

1
这对于IE7 / 8非常有用。干杯@Niet the Dark Absol
ojhawkins

min和max遍历数组以获取其值不一定是正确的。他们对数组进行快速排序并根据结果选择最小值和最大值是更可行的方法
Goonerify

7
@goonerify最快的排序是O(n log n),其本质上比O(n)仅扫描一次的速度慢...
Niet the Dark Absol 2015年

11

您可以尝试:

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

您也可以尝试 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);



3

这是一个允许您也返回键并且仅执行一次循环的解决方案。它对对象的条目进行排序(按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));


谢谢!我试图弄清楚如何获得最大值,同时又保留了与价值保持一致的关键。这有帮助!:)
010011100101

2

对于不同深度的嵌套结构,即{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;
    }
}

2
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))

3
当回答一个旧问题时,如果您包含一些上下文来解释您的答案如何帮助您的答案,则对于其他StackOverflow用户将更加有用,特别是对于已经接受了答案的问题。请参阅:如何写一个好的答案
David Buck

0

这对我有用:

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); });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.