javascript 查找数组中出现频率最高的项(不仅仅是字符串)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31227687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find the most frequent item of an array (not just strings)
提问by chichi
Can someone walk me through this exercise? Write a JavaScript program to find the most frequent item of an array.
有人可以指导我完成这个练习吗?编写一个 JavaScript 程序来查找数组中最频繁的项。
var arr1 = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];
var mf = 1;
var m = 0;
var item;
for (var i = 0; i < arr1.length; i++) {
for (var j = i; j < arr1.length; j++) {
if (arr1[i] == arr1[j]) m++;
if (mf < m) {
mf = m;
item = arr1[i];
}
}
m = 0;
}
alert(item + " ( " + mf + " times ) ");
I've been checking out some similar questions on stackoverflow, just can't find the answers that I want.
我一直在查看有关 stackoverflow 的一些类似问题,只是找不到我想要的答案。
My questions are:
我的问题是:
I don't understand why there needs to have two for loops.
Why the need for
mf
andm
. Seems a bit confusing.Is there other way of solution on this?
我不明白为什么需要有两个 for 循环。
为什么需要
mf
和m
。好像有点混乱。对此有其他解决方法吗?
回答by Ajay Narain Mathur
User want's explanation of the code:
用户想要的代码解释:
Here they select the 1st element of the array and compare it with every element then on.
在这里,他们选择数组的第一个元素,然后将其与每个元素进行比较。
Then they increment the counter m
every time the same elements occur again, frequency of that element.
然后,m
每次相同元素再次出现时,它们都会增加计数器,即该元素的频率。
Also a variable mf
is kept to keep track of maximum frequency. Compare the elements frequency with maximum frequency and update item
and mf
as per present element's frequency.
还mf
保留一个变量以跟踪最大频率。将元素频率与最大频率进行比较,item
并mf
根据当前元素的频率进行更新。
var arr1=[3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3]; //array
var mf = 1; //default maximum frequency
var m = 0; //counter
var item; //to store item with maximum frequency
for (var i=0; i<arr1.length; i++) //select element (current element)
{
for (var j=i; j<arr1.length; j++) //loop through next elements in array to compare calculate frequency of current element
{
if (arr1[i] == arr1[j]) //see if element occurs again in the array
m++; //increment counter if it does
if (mf<m) //compare current items frequency with maximum frequency
{
mf=m; //if m>mf store m in mf for upcoming elements
item = arr1[i]; // store the current element.
}
}
m=0; // make counter 0 for next element.
}
回答by Xotic750
I don't understand why there needs to have two for loops.
我不明白为什么需要有两个 for 循环。
There is no need for two loops, except for author choice.
除了作者选择之外,不需要两个循环。
Why the need for
mf
andm
. Seems a bit confusing.
为什么需要
mf
和m
。好像有点混乱。
They are necessary for the solution that the author has chosen.
它们对于作者选择的解决方案是必要的。
m
is the count of the current value being tested.
m
是正在测试的当前值的计数。
mf
is the current maximum frequency to test m
against and make a decision if the current element being tested is more frequent than the previously most frequent.
mf
是当前要测试的最大频率,m
并决定当前被测试的元素是否比以前最频繁的元素更频繁。
Is there other way of solution on this?
对此有其他解决方法吗?
Sure, plenty. Here is another one that takes things a step further.
当然,很多。这是另一个使事情更进一步的方法。
function getMostFrequentElement(inputArg) {
var type = typeof inputArg,
length,
mostFrequent,
counts,
index,
value;
if (inputArg === null || type === 'undefined') {
throw TypeError('inputArg was "null" or "undefined"');
}
mostFrequent = [];
if (type === 'function' || !Object.prototype.hasOwnProperty.call(inputArg, 'length')) {
mostFrequent[0] = inputArg;
mostFrequent[1] = 1;
} else {
counts = {};
length = inputArg.length;
for (index = 0; index < length; index += 1) {
value = inputArg[index];
type = typeof value;
counts[type] = counts[type] || {};
counts[type][value] = (counts[type][value] || 0) + 1;
if (!mostFrequent.length || counts[type][value] >= mostFrequent[1]) {
mostFrequent[0] = value;
mostFrequent[1] = counts[type][value];
}
}
}
return mostFrequent;
}
function logMostFrequentElement(inputArg) {
var mostFrequentElement,
element,
text;
try {
mostFrequentElement = getMostFrequentElement(inputArg)
if (mostFrequentElement.length) {
element = mostFrequentElement[0];
if (typeof element === 'string') {
element = '"' + element + '"';
}
text = element + ' ( ' + mostFrequentElement[1] + ' times )';
} else {
text = 'No elements';
}
} catch (e) {
text = e.message;
}
document.getElementById('out').appendChild(document.createTextNode(text + '\n'));
}
logMostFrequentElement();
logMostFrequentElement(1);
logMostFrequentElement(true);
logMostFrequentElement(function (x) { return x; });
logMostFrequentElement(/ab/g);
logMostFrequentElement([]);
logMostFrequentElement([1, 2]);
logMostFrequentElement([1, NaN, 2, NaN, 'NaN']);
logMostFrequentElement([1, Infinity, 2, Infinity, 'Infinity', -Infinity]);
logMostFrequentElement(['1', '2', 1, '2', 2]);
logMostFrequentElement([3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3]);
logMostFrequentElement([34, 'ab', 'ab', 'ab', 21, 34, 'ab', 34, 'ab', 21, 45, 99, 34]);
logMostFrequentElement('Also works with strings.');
<pre id="out"></pre>
回答by arnabkaycee
I really do not think there is a need for 2 loops in this solution. You can look at this prototyping code which uses a simple data structure called map:
我真的不认为在这个解决方案中需要 2 个循环。你可以看看这个原型代码,它使用了一个叫做 map 的简单数据结构:
var arr=[3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];
var map = {};
var mostFrequentElement = arr[0];
function findMostFrequent(){
for(var i = 0; i<arr.length; i++){
if(!map[arr[i]]){
map[arr[i]]=1;
}else{
++map[arr[i]];
if(map[arr[i]]>map[mostFrequentElement]){
mostFrequentElement = arr[i];
}
}
}
alert(mostFrequentElement);
}
回答by Walter Chapilliquen - wZVanG
Using Array.prototype.reduce()and a temporary variable, You could do it this way (4 lines):
使用Array.prototype.reduce()和一个临时变量,你可以这样做(4 行):
var arr2 = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];
var newArr = arr2.slice().sort(), most = [undefined, 0], counter = 0;
newArr.reduce(function(old, chr){
old == chr ? ++counter > most[1] && (most = [chr, counter]) : (counter = 1)
return chr
});
alert(most[0] + " ( "+most[1]+" times )");
ExplanationExcuse my english.
解释请原谅我的英语。
Using Array.prototype.reduce()can simplify your work. The following function first sorts their characters as 22333349aaaaa
, then this counts your characters in sequence. I created a temp variable most
to store the data of the character most repeated.
使用Array.prototype.reduce()可以简化您的工作。以下函数首先将它们的字符排序为22333349aaaaa
,然后按顺序计算您的字符。我创建了一个临时变量most
来存储重复次数最多的字符的数据。
NoteThis only works for items of single digits.
Note这仅适用于个位数的项目。
回答by Walter Chapilliquen - wZVanG
This is an answer to point (3) using underscore:
这是使用下划线对第 (3) 点的回答:
function length(a) { return a.length; }
_.max(_.groupBy(arr1), length)[0]
How this works:
这是如何工作的:
> arr1 = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];
> groups = _.groupBy(arr1)
< { 2: [2,2], 3: [3,3,3,3], 4: [4], 9: [9], a: ['a', 'a', ...] }
> max_group = _.max(groups, length)
< ['a', 'a', ...]
> max_group [0]
< 'a'
回答by RIYAJ KHAN
Please try this one.
请试试这个。
var mostFrequnet = null,mostFrequnetItem ;
var arr1 = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];
arr1.sort();
for (var i=0;i<arr1.length;i++){
var single = arr1[i];
var total = (arr1.lastIndexOf(single)-arr1.indexOf(single))+1;
if(total > mostFrequnet) {
mostFrequnetItem = arr1[i];
mostFrequnet = total;
i= arr1.lastIndexOf(single)+1;
}
}
console.log(mostFrequnet);
console.log(mostFrequnetItem);
回答by Bibek Sharma
var nums = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3]; //array
var freqs = {};
var max_index;
var max_value = -1/0; // Negative infinity.
$.each(nums, function(i, v) {
if (freqs[v] != undefined) {
freqs[v]++;
} else {
freqs[v] = 1;
}
});
$.each(freqs, function(num, freq) {
if (freq > max_value) {
max_value = freq;
max_index = num;
}
});
if(max_index != undefined) {
alert("Most common element is " + max_index + " with " + max_value + " repetition(s).");
}