下划线.js:查找数组中出现频率最高的值
Underscore.js: Find the most frequently occurring value in an array?
考虑以下简单数组:
var foods = ['hotdog', 'hamburger', 'soup', 'sandwich', 'hotdog', 'watermelon', 'hotdog'];
对于underscore
,是否有一个函数或函数组合可以用来选择最常出现的值(在本例中为hotdog
)?
var foods = ['hotdog', 'hamburger', 'soup', 'sandwich', 'hotdog', 'watermelon', 'hotdog'];
var result = _.chain(foods).countBy().pairs().max(_.last).head().value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
计数: 将列表分组并返回对象数的计数 在每个组中。
对: 将对象转换为
[key, value]
对的列表。最大: 返回列表中的最大值。如果提供了迭代器函数,它将用于每个值以生成对值进行排名的标准。
最后: 返回数组的最后一个元素
头: 返回数组的第一个元素
链条: 返回换行的对象。对此对象调用方法将继续返回包装的对象,直到使用 value。
值: 提取包装对象的值。
您可以使用
_.reduce
一次性执行此操作。基本思想是同时跟踪单词频率和最常见的单词:
var o = _(foods).reduce(function(o, s) {
o.freq[s] = (o.freq[s] || 0) + 1;
if(!o.freq[o.most] || o.freq[s] > o.freq[o.most])
o.most = s;
return o;
}, { freq: { }, most: '' });
这让'hotdot'
o.most
演示:http://jsfiddle.net/ambiguous/G9W4m/
如果您不介意预先声明缓存变量,也可以使用 each
(甚至是简单的 for
循环)来做到这一点:
var o = { freq: { }, most: '' };
_(foods).each(function(s) {
o.freq[s] = (o.freq[s] || 0) + 1;
if(!o.freq[o.most] || o.freq[s] > o.freq[o.most])
o.most = s;
});
演示:http://jsfiddle.net/ambiguous/WvXEV/
您也可以o
分成两部分并使用上述略微修改的版本,这样您就不必说o.most
就可以'hotdog'
了。
根据以前的答案,这是我的版本,用于计算字符串或数字数组的模式,该数组考虑了模式中的绘制(当值具有相同的频率时)并返回频率。然后,您可以选择如何处理它们。
包括下划线和洛达什。
// returns
// [['item', frequency]] where item is a string and frequency is an interger
// [['item', frequency], ['item', frequency], ['item', frequency] ... ] for draws
// examples:
// unique mode: creed appears the most times in array
// returns: [['creed', 4]]
// draw mode: 'jim' and 'creed' both occur 4 times in array
// returns: [['jim', 4], ['creed', 4]]
// underscore:
const usMode = arr => _.chain(arr).countBy().pairs().value().sort((a, b) => b[1] - a[1]).filter((e,i,a) => e[1] === a[0][1])
// lodash
const ldMode = arr => _.chain(arr).countBy().toPairs().value().sort((a, b) => b[1] - a[1]).filter((e,i,a) => e[1] === a[0][1])
// usage
usMode([1,2,3,3,3,4,5,6,7])
// [['3', 3]]
使用下划线:
// underscore
const strsUniqueArr = ['jim','pam','creed','pam','jim','creed','creed','creed']
const strsDrawArr = ['pam','jim','creed','jim','jim','creed','creed','creed', 'pam', 'jim']
const numsUniqueArr = [1, 2, 2, 2, 2, 3 ,4, 5]
const numsDrawArr = [1, 1, 1, 1, 2, 2, 2, 2, 3 ,4, 5]
const usMode = arr => _.chain(arr).countBy().pairs().value().sort((a, b) => b[1] - a[1]).filter((e,i,a) => e[1] === a[0][1])
console.log('empty', usMode([]))
console.log('unique strs', usMode(strsUniqueArr))
console.log('draw sts', usMode(strsDrawArr))
console.log('unique nums', usMode(numsUniqueArr))
console.log('draw nums', usMode(numsDrawArr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
使用 lodash:
// lodash
const strsUniqueArr = ['jim','pam','creed','pam','jim','creed','creed','creed']
const strsDrawArr = ['pam','jim','creed','jim','jim','creed','creed','creed', 'pam', 'jim']
const numsUniqueArr = [1, 2, 2, 2, 2, 3 ,4, 5]
const numsDrawArr = [1, 1, 1, 1, 2, 2, 2, 2, 3 ,4, 5]
const ldMode = arr => _.chain(arr).countBy().toPairs().value().sort((a, b) => b[1] - a[1]).filter((e,i,a) => e[1] === a[0][1])
console.log('empty', ldMode([]))
console.log('unique strs', ldMode(strsUniqueArr))
console.log('draw sts', ldMode(strsDrawArr))
console.log('unique nums', ldMode(numsUniqueArr))
console.log('draw nums', ldMode(numsDrawArr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
相关文章:
- 可以't让我的if语句处理js中的html表单输入
- 使用agility.js进行页面布局和合成
- 使用Clipboard.js复制span文本
- 使用JS如何动态更改显示的html文件中的文本背景颜色
- 强制模板刷新ember.js
- 如何编写HTML输入的JS内联
- Angular JS IE9 Hashbang url rewriting
- 使用JS将数组转换为json对象
- Node.js v6.2.0类扩展不是函数错误
- 当js函数's已执行
- 要求未定义JS回调参数
- 在自定义mean.io包中使用angular-chart.js作为依赖项
- 根据已经给定的频率创建一个d3.js直方图
- 正弦波.js设置新频率时不会播放多个音符
- 下划线.js:查找数组中出现频率最高的值
- 按频率排序子字符串数组-JS
- 使用D3.js创建频率计数饼状图
- D3.js直方图不能与每个箱子的总频率数组一起工作
- 在Node.js中,如何以不同的频率更新页面的不同组件
- 使用moment js计算时间在两个日期之间发生的频率