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

时间:2013-05-12 15:43:31

标签: javascript jquery arrays object

我有一个包含对象的数组:

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

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

我不知道我的数组中会有多少个对象但是它们的属性都有不同的值,我在这里给出了一些例子。

问题

我需要找到一种方法来遍历所有这些对象并检索article.number中具有最高值的对象的索引。我怎样才能做到这一点?我可能只使用javascript,jQuery等。没有其他语言。

我猜这将涉及同时使用$ .grep和Math.max但是我被卡住了,我以前从未使用$ .grep。

简而言之:

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

7 个答案:

答案 0 :(得分:14)

有很多方法可以做到这一点,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

答案 1 :(得分:11)

Underscore.js是一个很棒的库,可以为集合提供功能操作。下划线的解决方案:

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

虽然这个例子非常简单,但操作规模很好。假设您想要对数组中每个对象的数字属性求和,该对象的文本等于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();  

如果您完全关心性能,那么外部库肯定是可行的方法。外部库可以提供大量的优化,这些优化很难在您自己的代码中匹配。也就是说,当处理少量项目(少于几千个)时,这里发布的任何答案之间都不会有明显的性能差异。不要为基准测试而烦恼,并使用对您来说最容易理解的答案。

JSFiddle

答案 2 :(得分:5)

怎么样:

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

如果您需要索引:

index = articles.indexOf(articleWithMaxNumber)

对于那些认为排序可能是一个过度杀手来获得最大值的人:

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

以下是如何使用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 })

与迭代的方法相比,有些人对sort方法“缓慢”感到担忧。这是fiddle,它使用两种方法处理 50000项的数组。 sort方法在我的机器上“慢”约 50毫秒。取决于应用程序,但在大多数情况下,这不值得讨论。

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

答案 3 :(得分:1)

这是一种可能的解决方案

的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]);

jsfiddle

以下是当前给定方法的performance test,随时添加答案。

答案 4 :(得分:1)

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

答案 5 :(得分:0)

我不会使用像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 !

只要你的记忆中没有文章,这是最快的方法。

答案 6 :(得分:0)

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

表示使用索引(i)获取元素,其中(i)是最大数字的索引。