I was trying to solve a most popular item in array problem.
I found some O(n) solutions using maps but nothing that quite works when you have mixed data types, let's say
[1,2,1,3,"1","a"]
The "1" get's mixed with the 1. Any chance I can override comparison within JS? Or any O(n) solution that might fix it?
That was the most popular array element that I was using, taking in consideration that you can have more than one with the same amount:
function getMostFrequent(array) {
if (array.length == 0)
return null;
let mapEl = {};
let maxEl = [];
let maxCount = 1;
for (let i = 0; i < array.length; i++) {
let el = array[i];
if (mapEl[el] == null) {
mapEl[el] = 1;
} else {
mapEl[el]++;
}
if (mapEl[el] > maxCount) {
maxCount = mapEl[el];
maxEl = [el];
} else if (mapEl[el] === maxCount) {
maxEl.push(el);
}
}
console.log(maxEl);
return maxEl;
}
some O(n) solutions using maps
Map
s work just fine, because map "keys" can be any type, including numbers, strings, and objects (which are differentiated):
const input = [1,2,1,3,"1", "1", "1", "a"];
const map = new Map();
input.forEach(key => map.set(key, (map.get(key) || 0) + 1));
console.log(
[...map.entries()].reduce((a, b) => b[1] > a[1] ? b : a)
);
Could also use reduce
, which is a bit more appropriate for this situation:
const input = [1,2,1,3,"1", "1", "1", "a"];
const map = input.reduce(
(map, key) => map.set(key, (map.get(key) || 0) + 1),
new Map()
);
console.log(
[...map.entries()].reduce((a, b) => b[1] > a[1] ? b : a)
);
Yes, these are O(N)
.