下划线:找到数组中出现频率最高的对象?
Underscore: Find the most frequently occurring object in an array?
我这里有一个对象数组。
var list = [
{"id": 439, "name": "John"},
{"id": 439, "name": "John"},
{"id": 100, "name": "Kevin"},
{"id": 120, "name": "Max"},
{"id": 439, "name": "John"}
];
我需要从这个数组中提取最常出现的对象,并构建一个按最常用名称排序的新数组。
到目前为止,我已尝试按照本主题的完成方式进行操作:Underscore.js: Find the most frequently occurring value in an array?
// 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])
});
});
是否可以通过直接排序初始列表而不需要创建临时列表来改进此代码?
您差不多明白了:您可以在 reverse
调用之后立即调用地图。这是我的做法:
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: returns a wrapped version of the array, that let's you chain underscore functions.
countBy: returns an object where the keys are whatever value is returned from the callback, and the values are the number of times those keys occured.
pairs: converts { key: 'value' }
to ['key', 'value']
sortBy: returns an array sorted by the value returned from the callback
reverse: reverses the array
map: returns a new array where each item is based on the item in the original array at that index and whatever is done to that value in the callback. In this case, we're using the id
(item[0]
) to get the object from the original list.
value: unwraps the chain-able object and returns the "raw" value.
您可以使用reduce, to get a count of items, after that a 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>
_.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>
我这里有一个对象数组。
var list = [
{"id": 439, "name": "John"},
{"id": 439, "name": "John"},
{"id": 100, "name": "Kevin"},
{"id": 120, "name": "Max"},
{"id": 439, "name": "John"}
];
我需要从这个数组中提取最常出现的对象,并构建一个按最常用名称排序的新数组。
到目前为止,我已尝试按照本主题的完成方式进行操作:Underscore.js: Find the most frequently occurring value in an array?
// 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])
});
});
是否可以通过直接排序初始列表而不需要创建临时列表来改进此代码?
您差不多明白了:您可以在 reverse
调用之后立即调用地图。这是我的做法:
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: returns a wrapped version of the array, that let's you chain underscore functions.
countBy: returns an object where the keys are whatever value is returned from the callback, and the values are the number of times those keys occured.
pairs: converts
{ key: 'value' }
to['key', 'value']
sortBy: returns an array sorted by the value returned from the callback
reverse: reverses the array
map: returns a new array where each item is based on the item in the original array at that index and whatever is done to that value in the callback. In this case, we're using the
id
(item[0]
) to get the object from the original list.value: unwraps the chain-able object and returns the "raw" value.
您可以使用reduce, to get a count of items, after that a 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>
_.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>