简体   繁体   English

查找属性中具有最高值的数组中的对象索引

[英]Find index of object in array with highest value in property

I've got an array with objects: 我有一个包含对象的数组:

var articles = [];
var article = {};

Simple loop that iterates x times {
        article.text = "foobar";
        article.color = "red";
        article.number = 5;
        articles.push(article);
}

I have no idea how many objects there will be in my array but they will all have different values for their properties, I just gave some examples here. 我不知道我的数组中会有多少个对象但它们的属性都有不同的值,我在这里给出了一些例子。

Question

I need to find a way to go through all these objects and retrieve the index of the object that has the highest value in article.number. 我需要找到一种方法来遍历所有这些对象并检索article.number中具有最高值的对象的索引。 How can I achieve this? 我怎样才能做到这一点? I may only use javascript, jQuery, etc.. no other languages. 我可能只使用javascript,jQuery等。没有其他语言。

I'm guessing this will involve using both $.grep and Math.max but I'm stuck, I've never worked with $.grep before. 我猜这将涉及同时使用$ .grep和Math.max但是我被卡住了,我以前从未使用$ .grep。

In short: 简而言之:

var highestNumber = index of object where article.number is highest

There are many ways to do this, Math.max() , $.grep and $.map being a few, but an easy and readable method that should be understandable is to just iterate the object, and check if the value is higher than a variable, if it is, set the variable to the higher number : 有很多方法可以做到这一点, Math.max()$.grep$.map是一些,但一个易于理解的方法应该是可以理解的,只是迭代对象,并检查值是否高于变量,如果是,则将变量设置为更高的数字:

var highest = 0;

$.each(articles, function(key, article) {

    if (article.number > highest) highest = article.number;

});

// highest now contains the highest number

Underscore.js is a wonderful library that provides functional operations for collections. Underscore.js是一个很棒的库,可以为集合提供功能操作。 A solution in underscore: 下划线的解决方案:

var maxObj = _.max(array, function (obj) {
  return obj.number;
});
var maxIndex = array.indexOf(maxObj);

While this example is fairly simple, the operations scale nicely. 虽然这个例子非常简单,但操作规模很好。 Say you wanted to sum the number property for each object in the array that had text equal to Foo and color equal to red : 假设您想要对数组中每个对象的数字属性求和,该对象的文本等于Foo ,颜色等于red

var customSum = _.chain(array)
  .where({ 
    text: "Foo", color: "red"
  })
  .map(function(obj) {
    return obj.number; 
  })
  .reduce(function(memo, num) {
    return memo + num;
  }, 0)
  .value();  

If you're at all concerned with performance, an external library is certainly the way to go. 如果您完全关注性能,那么外部库肯定是可行的方法。 There are a huge amount of optimizations that external libraries can provide that would be difficult to match in your own code. 外部库可以提供大量的优化,这些优化很难在您自己的代码中匹配。 That said, when dealing with a small number of items (less than several thousand) there won't be an appreciable performance difference between any of the answers posted here. 也就是说,当处理少量项目(少于几千个)时,这里发布的任何答案之间都不会有明显的性能差异。 Don't sweat the benchmarking and use the answer that's the most understandable to you. 不要冒出基准测试并使用对您来说最容易理解的答案。

JSFiddle 的jsfiddle

How about: 怎么样:

articleWithMaxNumber = articles.slice(0).sort(
     function(x, y) { return y.number - x.number })[0]

and if you need an index: 如果你需要一个索引:

index = articles.indexOf(articleWithMaxNumber)

And for those thinking sorting might be an overkill to get the max value: 对于那些认为排序可能是一个过度杀手来获得最大值的人:

articleWithMaxNumber = articles.reduce(function(max, x) {
    return x.number > max.number ? x : max;
})

And here's a generic approach how to find a maximum of function applications using map-reduce: 以下是如何使用map-reduce查找最多函数应用程序的通用方法:

function maxBy(array, fn) {
    return array.map(function(x) {
        return [x, fn(x)]
    }).reduce(function(max, x) {
        return x[1] > max[1] ? x : max;
    })[0]
}

articleWithMaxNumber = maxBy(articles, function(x) { return x.number })

Some people raised concerns about the sort method being "slow", compared to the iterative one. 与迭代方法相比,有些人对sort方法“慢”提出了担忧。 Here's a fiddle that uses both methods to process an array with 50000 items . 这是一个小提琴 ,它使用两种方法处理一个包含50000个项目的数组。 The sort method is "slower" by about 50 milliseconds on my machine. sort方法在我的机器上“慢”约50毫秒 Depends on the application, but in most cases this is not something worth talking about. 取决于应用程序,但在大多数情况下,这不值得讨论。

 var articles = []; var len = 50000; while (len--) { var article = {}; article.text = "foobar"; article.color = "red"; article.number = Math.random(); articles.push(article); } d = performance.now(); max1 = articles.slice(0).sort( function(x, y) { return y.number - x.number })[0] time1 = performance.now() - d d = performance.now(); max2 = articles.reduce(function(max, x) { return x.number > max.number ? x : max; }) time2 = performance.now() - d document.body.innerHTML = [time1, time2].join("<br>") 

Here is one possible solution 这是一种可能的解决方案

Javascript 使用Javascript

var articles = [],
    howMany = 5,
    i = 0,
    article,
    highest;

while (i < howMany) {
    article = {};
    article.text = "foobar";
    article.color = "red";
    article.number = i;
    articles.push(article);
    i += 1;
}

console.log(articles);

hownMany = articles.length;
i = 0;
while (i < howMany) {
    if (typeof highest !== "number" || articles[i].number > highest) {
        highest = i;
    }

    i += 1;
}

console.log(articles[highest]);

On jsfiddle jsfiddle

Here is the performance test for the current given methods, feel free to add answers. 这是当前给定方法的性能测试 ,随意添加答案。

items => 
    items
        .reduce(
            ( highest, item, index ) => 
                item > highest.item 
                    ? { item, index }
                    : highest
        ,   { item: Number.NEGATIVE_INFINITY }
        )
        .index

I won't use anything like Math or jQuery, just sort the resulting array and popping off the last element: 我不会使用像Math或jQuery这样的东西,只需对生成的数组进行排序并弹出最后一个元素:

var sortArticles = function (a, b)
{
    return ( a.number - b.number ); // should have some type checks ? inverse order: swap a/b
}

articles.sort(sortArticles);


highestArticle = articles.pop(); // or articles[array.length-1]; 
// take care if srticles.length = null !

As long as you don't have gazillions of articles in your memory, that's the fastest way. 只要你的记忆中没有文章,那就是最快的方法。

array[array.map((o)=>o.number).indexOf(Math.max(...array.map((o)=>o.number)))]

意味着获得具有索引​​(i)的元素,其中(i)是最高数字的索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM