Reputation:
I'm using the following function to get the most frequent item of an array:
Array.prototype.array_most_frequent = function() {
var m=0, mf=0;
for (var i=0; i<this.length; i++) {
for (var j=i; j<this.length; j++)
{
if (this[i] == this[j]) m++;
if (mf<m) {mf=m; item = this[i]; }
}
m=0;
}
return item;
}
Works fine - but how to get the rarest item of an array?
For example var array=[2,1,2,5,5]
should return '1
'.
Is there an easy way to the least frequent item of my array?
Thanks in advance.
Upvotes: 1
Views: 4069
Reputation: 65
The short solution could be this, if the sort function don't mutate the array, even passing the parameter by a function. (If passing for a class constructor this will not happen.)
Modifying a little bit... this.
const arr = [2, 1, 2, 5, 5];
const result = arr.sort((a,b) =>
arr.filter(v => v===b).length
- arr.filter(v => v===a).length
).pop();
console.log(result)
But sometimes mutability is not desired and that could be an inconvenient, so follow in bellow a solution with no mutability:
Based in a this solution, that just count and add for a object, the name of repeated value and how much times it happen. After that, just take the least one, search in object by the least value to return the name of key that least is repeated.
const arr = [2, 1, 2, 5, 5];
const reducedOnes = arr.reduce((acc, val) => ({...acc, [val]: (acc[val] || 0) + 1}), {});
const leastFrequency = Math.min(...Object.values(reducedOnes));
const leastItem = Object.keys(reducedOnes).find(el=>reducedOnes[el]===leastFrequency);
console.log(leastItem);
Upvotes: 1
Reputation: 1
const arr = [1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4]
function leastFrequent(items) {
let leastFrequentNumber = items[0]
const counted = items.reduce((acc, item) => {
if (!acc[item]) {
acc[item] = 1
} else {
acc[item]++
}
if(acc[item] < acc[leastFrequentNumber]) {
leastFrequentNumber = item
}
return acc;
}, {});
return leastFrequentNumber
}
console.log(leastFrequent(arr)) //3
Upvotes: 0
Reputation: 56
You can create a dictionary for counting the occurrences of array elements, and then return the key for the lowest count.
function rarestFromArray(arr) {
// Create dictionary with array element as key and occurence count as value
var arrMap = arr.reduce(function(obj, val) {
obj[val] = ++obj[val] || 1;
return obj;
}, {});
// Cache first element as the point of reference
var rarest = Object.keys(arrMap)[0];
// Compare and return the lowest count
for (key in arrMap) {
// gets first occurence of lowest count
rarest = arrMap[rarest] > arrMap[key] ? key : rarest;
// gets last occurence of lowest count
// rarest = arrMap[rarest] < arrMap[key] ? rarest : key;
}
return rarest;
}
var inputArr = [1, 1, 1, 1, 2, 2, 2, 3, 33, 4, 4];
console.log(rarestFromArray(inputArr));
Upvotes: 0
Reputation: 191976
An ES6 solution that creates a Map of occurrences using Array#reduce. Then spread the map to get the entries, and reduce the entry to the entry with the smallest number of occurrences:
const array=[2,1,2,5,5];
const result = [...array.reduce((r, n) => // create a map of occurrences
r.set(n, (r.get(n) || 0) + 1), new Map()
)]
.reduce((r, v) => v[1] < r[1] ? v : r)[0]; // get the the item that appear less times
console.log(result);
Upvotes: 4
Reputation: 8716
ES6-way without unused iterating:
const getRarest = originalArray => {
const temp = {};
const counts = originalArray
.map(item => {
temp[item] = 0;
return item;
})
.reduce((acc, item) => {
acc[item]++;
return acc;
}, temp);
const resultArray = Object.entries(counts).sort(
([key, val], [bKey, bVal]) => bVal < val
);
return (rarest = parseInt(resultArray[0][0]));
};
//Implementation
const arr = [3, 2, 4, 4];
console.log(getRarest(arr));
Upvotes: 0
Reputation: 2509
You could use a hash to track occurrences then return min
value of its values.
function leastFrequent(arr) {
var dict = {};
arr.forEach(function(el) {
if (!dict[el]) dict[el] = 0;
dict[el]++;
});
return Math.min.apply(null, Object.values(dict));
}
// ES6+
const leastFrequent = arr => {
const dict = {};
arr.forEach(function(el) {
if (!dict[el]) dict[el] = 0;
dict[el]++;
});
return Math.min(...Object.values(dict));
}
Cheers
Upvotes: 1
Reputation: 3165
var arr = [2,1,2,5,5];
var frequencyMap = {};
for(var i=0; i<arr.length; i++) {
frequencyMap[arr[i]] = frequencyMap[arr[i]] || 0;
frequencyMap[arr[i]]++;
}
var maxValue = 0,maxFreq=0, minValue=NUMBER.MAX_INTEGER,minFreq=0;
for (var key in frequencyMap) {
if (frequencyMap[key] > maxFreq){
maxFreq = frequencyMap[key];
maxValue = key;
}else if (frequencyMap[key] < minFreq){
minFreq = frequencyMap[key];
minValue = key;
}
}
Upvotes: 0