假设我有一个类似的数组:
fruit_basket = ['apple', 'orange', 'banana', 'pear', 'banana']
我想制作一个数组fruits
,它由fruit basket
中的水果组成,按最常出现的水果顺序排序。 (如果有关系,我不在乎订购。)
fruits
的一个有效值是:
['banana', 'orange', 'apple', 'pear']
使用LoDash实现此目的的最简洁方法是什么?我不关心运行时性能。
答案 0 :(得分:2)
首先你要计算出现次数
var x = _.chain(fruit_basket).countBy(); // {apple: 1, orange: 1, banana: 2, pear: 1}
然后你将它们配对并按出现次数排序,使用reverse
获得最大数字
var y = x.toPairs().sortBy(1).reverse(); //[["banana",2],["pear",1],["orange",1],["apple",1]]
然后你只需映射回键,并将值作为数组
var arr = y.map(0).value(); // ['banana', 'orange', 'apple', 'pear']
所有链接在一起,看起来像
var arr = _.chain(fruit_basket).countBy().toPairs().sortBy(1).reverse().map(0).value();
没有loDash,这样的事情就可以了
var fruit_basket = ['apple', 'orange', 'banana', 'pear', 'banana'];
var o = {};
fruit_basket.forEach(function(item) {
item in o ? o[item] += 1 : o[item] = 1;
});
var arr = Object.keys(o).sort(function(a, b) {
return o[a] < o[b];
});
答案 1 :(得分:1)
这是我的看法。
它不使用lodash的问题。这是一种香草替代品。我觉得这对于那些从Google登陆到这里并且不想使用lodash的人来说可能是有价值的(至少我是从这里来的)。
const orderByCountAndDedupe = arr => {
const counts = new Map();
arr.forEach( item => {
if ( !counts.has(item) ) {
counts.set(item, 1);
} else {
counts.set(item, counts.get(item)+1);
}
});
return (
Array.from(counts)
.sort( (a, b) => b[1] - a[1])
.map( ([originalItem, count]) => originalItem)
);
};
答案 2 :(得分:0)
使用for
循环Array.prototype.splice()
var fruit_basket = ['apple', 'orange', 'banana', 'pear', 'banana'];
var res = [];
for (var i = 0; i < fruit_basket.length; i++) {
var index = res.indexOf(fruit_basket[i]);
// if current item does not exist in `res`
// push current item to `res`
if (index == -1) {
res.push(fruit_basket[i])
} else {
// else remove current item , set current item at index `0` of `res`
res.splice(index, 1);
res.splice(0, 0, fruit_basket[i])
}
}
console.log(res)
答案 3 :(得分:0)
您可以使用_.countBy计算出现次数,然后在_.sortBy中使用它:
var counter = _.countBy(fruit_basket)
var result = _(fruit_basket).uniq().sortBy(fruit => counter[fruit]).reverse().value()