下划线: 找到数组中出现频率最高的对象?

4

我这里有一个对象数组。

var list = [
    {"id": 439, "name": "John"},
    {"id": 439, "name": "John"},
    {"id": 100, "name": "Kevin"},
    {"id": 120, "name": "Max"},
    {"id": 439, "name": "John"}
];

我需要从这个数组中提取出最常出现的对象,并构建一个按最流行名称排序的新数组。
到目前为止,我尝试按照这个主题中的方式进行操作:Underscore.js:在数组中查找最常出现的值?
// Build temp list
temp_list = _(
    _.chain(
        _(list).pluck('id')
    )
    .countBy()
    .pairs()
    .value()
)
.sortBy(1)
.reverse();

// Build final list with most frequently occurring first
_.map(temp_list, function(current) {
    return _.findWhere(list, {
        'id': parseInt(current[0])
    });
});

有没有一种方法可以直接对初始列表进行排序,而不需要创建临时列表来改进此代码?


2
你的数组中所有对象都是不同的。如果它们的 idname 属性相同,你想要将两个对象视为相等吗?只考虑 id 属性? - Oriol
3个回答

3

您已经接近了答案:您可以直接在reverse调用后调用map函数。这是我是如何做到的:

var newlist = _.chain(list)
    .countBy(function (item) { return item.id; })
    .pairs()
    .sortBy(function (item) { return item[1]; })
    .reverse()
    .map(function (item) { return _.findWhere(list, { id: parseInt(item[0]) }); })
    .value();

简述如下:

chain: 返回包装版本的数组,使您可以链接underscore函数。

countBy: 返回一个对象,其中键是从回调返回的任何值,而值是发生这些键的次数。

pairs: 将{ key: 'value' }转换为['key', 'value']

sortBy: 返回按从回调返回的值排序的数组

reverse: 反转数组

map: 返回一个新数组,其中每个项目都基于原始数组中该索引处的项目以及在回调中对该值执行的任何操作。 在这种情况下,我们使用id (item[0])从原始列表获取对象。

value: 解封链式对象并返回“原始”值。


2
_.chain(list)
    .countBy("id").pairs().sortBy()
    .reverse().map(function (element) {return _.findWhere(list, { id: parseInt(element[0]) }); }).value()

var list = [
    {"id": 439, "name": "John"},
    {"id": 439, "name": "John"},
    {"id": 100, "name": "Kevin"},
    {"id": 120, "name": "Max"},
    {"id": 439, "name": "John"}
];
var result = _.chain(list)
    .countBy("id").pairs().sortBy()
    .reverse().map(function (element) {return _.findWhere(list, { id: parseInt(element[0]) }); }).value();
console.log(result);
document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>


0

你可以使用reduce来获取项目数量,然后再使用sortBy进行排序。

就像这样

var list = [
    {"id": 439, "name": "John"},
    {"id": 439, "name": "John"},
    {"id": 100, "name": "Kevin"},
    {"id": 120, "name": "Max"},
    {"id": 439, "name": "John"}
];

var finalList = _.chain(list)
 .reduce(function(memo, item){
 var previous = _.findWhere(memo,{id:item.id});
  if(previous){
   previous.count++;
  }else{
   item.count=1;
   memo.push(item);
  }
  return memo;
},[])
 .sortBy('count')
  .reverse()
  .value();
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接