查找对象数组中属性的最大值

Rio*_*Rio 345 javascript json

我正在寻找一种非常快速,干净和有效的方法来获取以下JSON切片中的最大"y"值:

[
  {
    "x": "8/11/2009",
    "y": 0.026572007
  },
  {
    "x": "8/12/2009",
    "y": 0.025057454
  },
  {
    "x": "8/13/2009",
    "y": 0.024530916
  },
  {
    "x": "8/14/2009",
    "y": 0.031004457
  }
]
Run Code Online (Sandbox Code Playgroud)

for循环是唯一可行的方法吗?我热衷于某种方式使用Math.max.

tob*_*ies 629

要查找y对象的最大值array:

Math.max.apply(Math, array.map(function(o) { return o.y; }))
Run Code Online (Sandbox Code Playgroud)

  • 你能扩展这个答案来展示如何返回找到最大值的对象吗?那将是非常有帮助的,谢谢! (41认同)
  • @MikeLyons如果您仍然关心获取实际对象:https://jsfiddle.net/45c5r246/34/ (22认同)
  • 这是小提琴!希望这会对某人有所帮助https://jsfiddle.net/45c5r246/ (17认同)
  • FWIW我的理解是当你在函数上调用apply时,它执行具有指定值的函数`this`和一系列指定为数组的参数.诀窍是apply将数组转换为一系列实际的函数参数.所以在这种情况下,它最终调用`Math.max(0.0265,0.0250,0.024,0.031)`,执行的函数`this`为`Math`.我不明白为什么它应该是`Math`坦率地说,我认为这个函数不需要有效的`this`.哦,这是一个正确的解释:http://stackoverflow.com/questions/21255138/how-does-the-math-max-apply-work (12认同)
  • 请大家回答! (9认同)
  • 这种方法不可取,最好使用reduce。对于大数组,apply 将使用大量参数调用 max,这可能会导致堆栈溢出。请参阅:/sf/ask/2156675951/ (4认同)
  • 获取最大值的更简洁的代码片段:`Math.max(...array.map(o => oy))` (3认同)
  • `Math.max.apply(Math,Array)`返回给定数组的最大值.`array.map(function(o){return oy;})`返回对象中y值的数组.然后在小提琴的第二行`array.find(function(o){return oy == valueReturnedByMathMax;})`中,你只需查找包含该最大值的对象. (2认同)
  • 注意仅当数组不为空时才调用此函数,否则返回值将为“Infinity” (2认同)
  • Math.max(... array.map(o => oy))<3 thx to atom code formatter (2认同)
  • 但是如果数组中有两个具有相同值的对象呢?`{“x”:“8/11/2009”,“y”:0.026572007},{“x”:“10/11/2009”,“y”:0.026572007}`。我的意思是发现会在第一次出现时停止,但是 Math.min 呢? (2认同)
  • 这不会遍历所有对象两次吗?Reduce 会避免这种情况,并让您更灵活地返回对象或值。请参阅下面的减少答案(由其他人提供)。即使没有reduce,编写一个将当前值存储在局部变量中并迭代一次并在必要时替换值的快速函数也会更好地工作(reduce基本上是这样做的) (2认同)

And*_*ill 206

在对象数组中查找属性"X"具有最大值的对象

一种方法是使用Array reduce ..

const max = data.reduce(function(prev, current) {
    return (prev.y > current.y) ? prev : current
}) //returns object
Run Code Online (Sandbox Code Playgroud)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce http://caniuse.com/#search=reduce(IE99及以上版本)

如果您不需要支持IE(仅限Edge),或者可以使用诸如Babel之类的预编译器,则可以使用更简洁的语法.

const max = data.reduce((prev, current) => (prev.y > current.y) ? prev : current)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这将返回对象中具有最大值而不是最大值的对象.这可能是也可能不是你想要的.就我而言,这就是我想要的.+1 (18认同)
  • 这是一个很好的答案,但是,您希望传递初始值,否则在数据数组为空时会出错.即对象的自动增量索引.`const max = data.reduce((prev,current)=>(prev.y> current.y)?prev:current,1)` (5认同)
  • 你提出了一个很好的观点,我可能会选择 `null` 而不是 1。 (3认同)
  • 另外,请确保数据类型是数字而不是字符串。否则你可能会得到好坏参半的结果。在适当的情况下使用“parseInt()”。 (2认同)

小智 120

干净简洁的ES6(巴别塔)

const maxValueOfY = Math.max(...arrayToSearchIn.map(o => o.y), 0);
Run Code Online (Sandbox Code Playgroud)

如果arrayToSearchIn为空,则第二个参数应确保默认值.

  • 当它为空数组返回`-Infinity`时,你可以传递**初始值**`Math.max(... state.allProjects.map(o => o.id),1);` (19认同)
  • 也很高兴知道它为空数组返回`-Infinity`(一个[truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)值) (8认同)
  • 这应该是现在接受的答案......绝对是更简洁的方法. (5认同)
  • 如何在此处获取对象? (2认同)

Guf*_*ffa 24

好吧,首先你应该解析JSON字符串,以便你可以轻松访问它的成员:

var arr = $.parseJSON(str);
Run Code Online (Sandbox Code Playgroud)

使用该map方法提取值:

arr = $.map(arr, function(o){ return o.y; });
Run Code Online (Sandbox Code Playgroud)

然后你可以在max方法中使用数组:

var highest = Math.max.apply(this,arr);
Run Code Online (Sandbox Code Playgroud)

或者作为一个单行:

var highest = Math.max.apply(this,$.map($.parseJSON(str), function(o){ return o.y; }));
Run Code Online (Sandbox Code Playgroud)

  • 它没有用`jQuery`标记 (14认同)
  • 如果@tobyodavies忽略了它被标记为"json"的事实并没有多大关系 - 他在答案中没有使用外部JavaScript库:) (7认同)

con*_*gus 22

我想逐步解释简洁的接受答案:

var objects = [{ x: 3 }, { x: 1 }, { x: 2 }];

// array.map lets you extract an array of attribute values
var xValues = objects.map(function(o) { return o.x; });
// es6
xValues = Array.from(objects, o => o.x);

// function.apply lets you expand an array argument as individual arguments
// So the following is equivalent to Math.max(3, 1, 2)
// The first argument is "this" but since Math.max doesn't need it, null is fine
var xMax = Math.max.apply(null, xValues);
// es6
xMax = Math.max(...xValues);

// Finally, to find the object that has the maximum x value (note that result is array):
var maxXObjects = objects.filter(function(o) { return o.x === xMax; });

// Altogether
xMax = Math.max.apply(null, objects.map(function(o) { return o.x; }));
var maxXObject = objects.filter(function(o) { return o.x === xMax; })[0];
// es6
xMax = Math.max(...Array.from(objects, o => o.x));
maxXObject = objects.find(o => o.x === xMax);


document.write('<p>objects: ' + JSON.stringify(objects) + '</p>');
document.write('<p>xValues: ' + JSON.stringify(xValues) + '</p>');
document.write('<p>xMax: ' + JSON.stringify(xMax) + '</p>');
document.write('<p>maxXObjects: ' + JSON.stringify(maxXObjects) + '</p>');
document.write('<p>maxXObject: ' + JSON.stringify(maxXObject) + '</p>');
Run Code Online (Sandbox Code Playgroud)

更多的信息:


Kam*_*ski 19

处理负数大小写的树ONELINERS的比较(在a数组中输入):

var maxA = Math.max(...a.map(o=>o.y),a[0].y); // 33 chars time complexity: >O(2n)

var maxB = a.reduce((a,b)=>a.y>b.y?a:b).y;    // 30 chars time complexity:  O(n)

var maxC = a.sort((a,b)=>b.y-a.y)[0].y;       // 27 chars time complexity:  O(nlogn)
Run Code Online (Sandbox Code Playgroud)

可编辑的示例在这里。想法来自:maxAmaxBmaxC(副作用:已更改a- sort已就位)。

var maxA = Math.max(...a.map(o=>o.y),a[0].y); // 33 chars time complexity: >O(2n)

var maxB = a.reduce((a,b)=>a.y>b.y?a:b).y;    // 30 chars time complexity:  O(n)

var maxC = a.sort((a,b)=>b.y-a.y)[0].y;       // 27 chars time complexity:  O(nlogn)
Run Code Online (Sandbox Code Playgroud)

对于更大的阵列,Math.max...将抛出异常:超出最大调用堆栈大小(Chrome 76.0.3809,Safari 12.1.2,日期2019-09-13)

var a = [
  {"x":"8/11/2009","y":0.026572007},{"x":"8/12/2009","y":0.025057454},    
  {"x":"8/14/2009","y":0.031004457},{"x":"8/13/2009","y":0.024530916}
]

var maxA = Math.max(...a.map(o=>o.y),a[0].y);
var maxB = a.reduce((a,b)=>a.y>b.y?a:b).y;
var maxC = a.sort((a,b)=>b.y-a.y)[0].y;


document.body.innerHTML=`<pre>maxA: ${maxA}\nmaxB: ${maxB}\nmaxC: ${maxC}</pre>`;
Run Code Online (Sandbox Code Playgroud)

  • 非常巧妙的方法来完成任务。好的 (3认同)

小智 13

这是最短的解决方案(One Liner)ES6

Math.max(...values.map(o => o.y));
Run Code Online (Sandbox Code Playgroud)

  • 同样,这对于大型数组来说是不安全的,因为它会导致堆栈溢出崩溃 (5认同)

小智 10

var data = [
  { 'name': 'Vins', 'age': 27 },
  { 'name': 'Jan', 'age': 38 },
  { 'name': 'Alex', 'age': 80 },
  { 'name': 'Carl', 'age': 25 },
  { 'name': 'Digi', 'age': 40 }
];
var max = data.reduce(function (prev, current) {
   return (prev.age > current.age) ? prev : current
});
//output = {'name': 'Alex', 'age': 80}
Run Code Online (Sandbox Code Playgroud)


Car*_*los 9

使用一个函数找到最大 obj.value 返回 obj

 let List= [{votes:4},{votes:8},{votes:7}]


let objMax = List.reduce((max, curren) => max.votes > curren.votes ? max : curren);

console.log(objMax)
Run Code Online (Sandbox Code Playgroud)

或者使用两个函数返回最大值

  Math.max(...List.map(el => el.votes)))
Run Code Online (Sandbox Code Playgroud)


kmo*_*oor 7

如果你(或者这里有人)可以自由使用lodash实用程序库,它有一个maxBy函数,在你的情况下非常方便.

因此你可以这样使用:

_.maxBy(jsonSlice, 'y');
Run Code Online (Sandbox Code Playgroud)


小智 5

或者简单的排序!保持真实:)

array.sort((a,b)=>a.y<b.y)[0].y
Run Code Online (Sandbox Code Playgroud)

  • 找到最大值的时间复杂度为 O(n)。这是 O(nlogn)。只要不牺牲效率,编写简单的代码就是好的。 (2认同)

Die*_*ezú 5

每个数组并使用 Math 获取最大值。

data.reduce((max, b) => Math.max(max, b.costo), data[0].costo);
Run Code Online (Sandbox Code Playgroud)