我有一个包含对象的数组:
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
答案 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();
如果您完全关心性能,那么外部库肯定是可行的方法。外部库可以提供大量的优化,这些优化很难在您自己的代码中匹配。也就是说,当处理少量项目(少于几千个)时,这里发布的任何答案之间都不会有明显的性能差异。不要为基准测试而烦恼,并使用对您来说最容易理解的答案。
答案 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]);
上
以下是当前给定方法的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)是最大数字的索引。