3

For example in underscore/lowdash you can use _.max(list, [iterator], [context]) function to receive one maximum value. But I want to have it returned multiple maximum values if they are all equal.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 50}];

_.max(stooges, function(stooge){ return stooge.age; });

=> {name: 'curly', age: 50};

I want to have somthing like this:

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 50}];

_.multiplemax(stooges, function(stooge){ return stooge.age; });

=> [{name: 'curly', age: 50},  {name: 'larry', age: 50 ];

Using underscore is ok.

2
  • Can it always return an array? Commented Nov 23, 2013 at 0:31
  • Obviously... result should be an array as well. Commented Nov 23, 2013 at 0:32

5 Answers 5

5

Is there any special requirements like you cant not combine multiple functions to do multiplemax. If no, I have 2 solutions in my mind

The simplest solution would be to use _.max to find the max age of the array, then use _.filter to filter all values that are equal to max age

Another solution is to use _.groupBy to group the array by age and then get the group with max age

Something like this

function multiplemax(arr, compare) {
  var groups = _.groupBy(arr, compare);
  var keys = _.keys(groups);
  var max = _.max(keys);
  return groups[max];
}

more "underscore"

_.mixin({
  multiplemax: function(arr, fn) {
    var groups = _.groupBy(arr, fn);
    var keys = _.keys(groups);
    var max = _.max(keys);
    return groups[max];
  }
})

Or using max + filter

function multiplemax(arr, compare) {
  var max = _.max(arr, function(v){return v[compare]});
  return _.filter(arr, function(v){return v[compare]==max[compare]});
}
Sign up to request clarification or add additional context in comments.

1 Comment

Note that the keys will be strings - so if you take the more "underscore" approach you may want to go for var max = _.max(keys, function (d) { return parseInt(d, 10); });
1

Something like this should do the trick.

_.mixin({
    multiplymax: function(items, comparitor) {
        comparitor = comparitor || _.identity;
        var max = comparitor(items.pop());
        var found = [max];
        _.each(items, function(item) {
            var val = comparitor(item);
            if(val > max) {
                found = [item];//empty
                max = val;
            } else if (val === max) {
                found.push(item);
            }
        });

        return found;
    }
})

Update fixed the broken code ;)

_.multiplymax([{age: 1}, {age:5}, {age:7}, {age:7}, {age:3}], _.property("age")); // [{age:7}, {age:7}]

Comments

1

This should do the trick:

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 50}];

_.mixin( { multiplemax: function(list, field){

    var max = _.max(list, function(item){
        return item[field];
    });

    return _.filter(list, function(item){
        return item[field] === max[field];
    });
}});    

var oldStooges = _.multiplemax(stooges, 'age');

Comments

1

Here is a modern version using TypeScript & ES6:

const multipleMaxBy = <T>(list: T[], iteratee: (element: T) => number) => {
  const maxScore = Math.max(...list.map(iteratee));
  return list.filter((element) => iteratee(element) === maxScore);
};

Comments

0

Sort it from highest to lowest and take amount of values:

export const multipleMax = (list: any[], amount: number = 1) => {
  return _.take(_.reverse(_.orderBy(list)), amount)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.