我正在寻找一种优雅的方法来确定JavaScript数组中出现率最高的元素(mode)。
例如,在以下数组中:
['pear', 'apple', 'orange', 'apple']
'apple'
元素是最常见的一个。
我正在寻找一种优雅的方法来确定JavaScript数组中出现率最高的元素(mode)。
例如,在以下数组中:
['pear', 'apple', 'orange', 'apple']
'apple'
元素是最常见的一个。
这个函数是通用的,适用于任何类型的信息。它计算元素出现的次数,然后返回具有最大出现元素的数组。
function mode () {
var arr = [].slice.call(arguments);
if ((args.length == 1) && (typeof args[0] === "object")) {
args = args[0].mode();
}
var obj = {};
for(var i = 0; i < arr.length; i++) {
if(obj[arr[i]] === undefined) obj[arr[i]] = 1;
else obj[arr[i]]++;
}
var max = 0;
for (w in obj) {
if (obj[w] > max) max = obj[w];
}
ret_val = [];
for (w in obj) {
if (obj[w] == max) ret_val.push(w);
}
return ret_val;
}
function getData(arr){
let obj = {}
let maxElementCount = 0
let maxEle = ''
for(let i = 0 ;i<arr.length;i++){
if(!obj[arr[i]]){
obj[arr[i]] = 1
}else{
obj[arr[i]] += 1
if(maxElementCount < obj[arr[i]]){
maxElementCount = obj[arr[i]]
maxEle = arr[i]
}
}
}
console.log(maxElementCount, maxEle)
return obj
}
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;
function getMode()
{
for (var i = 0; i < ct; i++)
{
value = num[i];
if (i != ct)
{
while (value == num[i + 1])
{
c = c + 1;
i = i + 1;
}
}
if (c > greatest)
{
greatest = c;
mode = value;
}
c = 0;
}
}
// works for all types of data within an array
function findMostRepeated(arr) {
const itemFrequencyMap = new Map()
for (let i = 0; i < arr.length; i++) {
if (itemFrequencyMap.has(arr[i])) {
itemFrequencyMap.set(arr[i], itemFrequencyMap.get(arr[i]) + 1)
} else {
itemFrequencyMap.set(arr[i], 1)
}
}
// console.log(itemFrequencyMap)
return Array.from(itemFrequencyMap).reduce((item1, item2) =>
item1[1] > item2[1] ? item1 : item2
)[0]
}
console.log(findMostRepeated(["pear", "apple", "orange", "apple"]))
我猜你有两种方法,都有优点。
排序再计数或者遍历并使用哈希表进行计数。
哈希表很好用,因为一旦处理完成,你还可以得到所有不同的元素。但如果有数百万项且重复率很低,则哈希表可能会占用大量内存。排序再计数的方法将具有更可控的内存占用。
const data = ['x','y','x','z',5,2,4,5,2,3,2,'x', { x: 1 }, (x) => x];
function getModeData(data) {
return data.reduce((a,c) => {
if(typeof a[c] === "undefined") {
a[c] = 1;
} else {
a[c]++;
}
if(
typeof a.mode === "undefined" ||
(typeof a.mode !== "undefined") && a.mode.occurrences < a[c]
) {
a.mode = {
elem: c,
occurrences: a[c]
}
}
return a;
}, { mode: undefined });
}
const { mode: { elem, occurrences }, ...totals } = getModeData(data);
console.log(`The mode is ${elem} with ${occurrences} occurrences`);
console.log('The totals are:');
console.log(totals)
//const arr = [1, 2, 4, 3, 5, 1, 2, 3, 3];
const arr = ['pear', 'apple', 'orange', 'apple'];
// init max occurance element
let maxOcc = {'element': null, occured: 0};
// to find occurances
const res = arr.reduce((acc, el) => {
acc[el] = acc[el] ? acc[el]+1 : 1;
if(acc[el]> maxOcc.occured){
maxOcc = { 'element': el, occured: acc[el] };
}
return acc;
}, {});
console.log(maxOcc);
已经有很多答案了,但我想和你分享一下我的想法 :) 不能说这个解决方案依赖于任何边缘情况,但无论如何)
const getMostFrequentElement = ( arr ) => {
const counterSymbolKey = 'counter'
const mostFrequentSymbolKey = 'mostFrequentKey'
const result = arr.reduce( ( acc, cur ) => {
acc[ cur ] = acc[ cur ] ? acc[ cur ] + 1 : 1
if ( acc[ cur ] > acc[ Symbol.for( counterSymbolKey ) ] ) {
acc[ Symbol.for( mostFrequentSymbolKey ) ] = cur
acc[ Symbol.for( counterSymbolKey ) ] = acc[ cur ]
}
return acc
}, {
[ Symbol.for( mostFrequentSymbolKey ) ]: null,
[ Symbol.for( counterSymbolKey ) ]: 0
} )
return result[ Symbol.for( mostFrequentSymbolKey ) ]
}
你可以用O(n)的复杂度解决它。
var arr = [1,3,54,56,6,6,1,6];
var obj = {};
/* first convert the array in to object with unique elements and number of times each element is repeated */
for(var i = 0; i < arr.length; i++)
{
var x = arr[i];
if(!obj[x])
obj[x] = 1;
else
obj[x]++;
}
console.log(obj);//just for reference
/* now traverse the object to get the element */
var index = 0;
var max = 0;
for(var obIndex in obj)
{
if(obj[obIndex] > max)
{
max = obj[obIndex];
index = obIndex;
}
}
console.log(index+" got maximum time repeated, with "+ max +" times" );
这是我的方法。我首先尝试对数据进行分组。
const _ = require("underscore")
var test = [ 1, 1, 2, 1 ];
var groupResult = _.groupBy(test, (e)=> e);
groupResult 应该是:
{
1: [1, 1, 1]
2: [2]
}
然后找到具有最长数组的属性
function findMax(groupResult){
var maxArr = []
var max;
for(var item in groupResult){
if(!max) {
max = { value:item, count: groupResult[item].length } ;
maxArr.push(max);
continue;
}
if(max.count < groupResult[item].length){
maxArr = [];
max = { value:item, count: groupResult[item].length }
maxArr.push(max)
} else if(max === groupResult[item].length)
maxArr.push({ value:item, count: groupResult[item].length })
}
return maxArr;
}
完整的代码如下所示
const _ = require("underscore")
var test = [ 1, 1, 2, 1 ];
var groupResult= _.groupBy(test, (e)=> e);
console.log(findMax(groupResult)[0].value);
function findMax(groupResult){
var maxArr = []
var max;
for(var item in groupResult){
if(!max) {
max = { value:item, count: groupResult[item].length } ;
maxArr.push(max);
continue;
}
if(max.count < groupResult[item].length){
maxArr = [];
max = { value:item, count: groupResult[item].length }
maxArr.push(max)
} else if(max === groupResult[item].length)
maxArr.push({ value:item, count: groupResult[item].length })
}
return maxArr;
}