Reputation: 448
Example:
hash = {'Apple':2, 'Orange' :1 , 'Mango' : 2}
here the maximum key is both Apple and Mango. How do I write a function which gives both Apple and Mango as answer.
I tried something like this :
Object.keys(hash).reduce(function(a, b){ return hash[a] > hash[b] ? a : b });
But this gives only Apple as the answer.
Upvotes: 5
Views: 5774
Reputation: 4592
I believe the requirements are traverse the array only once and results is an array of keys
const hash = {'Apple':2, 'Orange' :1 , 'Mango' : 2};
let max = 0;
let result = [];
Object.getOwnPropertyNames(hash).forEach(k => {
if (hash[k] > max) {
result = [k];
max = hash[k];
} else if (hash[k] === max) {
result.push(k);
}
});
console.log(result);
Upvotes: 0
Reputation: 8761
This works. If max
changes clear the result and set only the max
value.
var hash = {'Apple':2, 'Orange':1 , 'Mango':2, "Jackfruit":10, "Pineapple":5, "Tomato":-4};
var max="";
var result = Object.keys(hash).reduce(function(acc, val){
if(max < hash[val]) (max=hash[val], acc={});
if(hash[val]==max) acc[val] = hash[val];
return acc;
},{});
console.log(result)
Upvotes: 0
Reputation: 97162
You could first calculate the max value as a separate operation and then just filter:
const hash = {Apple: 2, Orange: 1, Mango: 2};
const max = Object.keys(hash).reduce((a, v) => Math.max(a, hash[v]), -Infinity);
const result = Object.keys(hash).filter(v => hash[v] === max);
console.log(result);
Simple and readable, but it requires and extra iteration, so it's not the most efficient implementation.
Upvotes: 4
Reputation: 370879
You might transform the object into one whose properties correspond to the count, whose values are the (original) property names in an array, and then get the value of the property with the maximum count:
const hash = {'Apple':2, 'Orange' :1 , 'Mango' : 2};
const indexedByCount = Object.entries(hash).reduce((a, [key, val]) => {
if (!a[val]) a[val] = [];
a[val].push(key);
return a;
}, {});
console.log(
indexedByCount[Math.max(...Object.keys(indexedByCount))]
);
A less functional but more efficient method would be to keep track of a max
variable corresponding to the maximum value found so far:
const hash = {'Apple':2, 'Orange' :1 , 'Mango' : 2};
let max = -Infinity;
console.log(
Object.entries(hash).reduce((a, [key, val]) => {
if (val > max) {
max = val;
return [key];
}
if (val === max) a.push(key);
return a;
}, [])
);
Upvotes: 1
Reputation: 19485
Your reduce
can only return a single value, but you need an array of values. So create one as the initial value.
In your function body, first, check whether your next key has a larger value, in which case you clear out the array.
Then, if your array is empty, or if the first contained key (and thus all keys) have the same value, push that key into your array.
Also, it helps if you give your arguments more expressive names.
Object.keys(hash).reduce(function(longestKeys, key){
if(hash[key] > hash[longestKeys[0]]){
longestKeys.length = 0;
}
if(longestKeys.length === 0 || hash[key] === hash[longestKeys[0]]){
longestKeys.push(key);
}
return longestKeys;
}, []);
Upvotes: 1