min_by,max_by等效函数在javascript中

时间:2014-09-17 11:09:12

标签: javascript

是否有任何javascript库包含Ruby中的min_by,max_by等函数,允许您传递lambda作为比较条件。我在JQuery和underscore.js中找不到这样的东西。

5 个答案:

答案 0 :(得分:20)

Chris的解决方案在阵列中运行三次;如果阵列很小,那很好,但它并不理想。您可以使用reduce将其转换为单次传递(使用Schwartzian变换的一种即用版本):

Array.prototype.minBy = function(fn) { return this.extremumBy(fn, Math.min); };

Array.prototype.maxBy = function(fn) { return this.extremumBy(fn, Math.max); };

Array.prototype.extremumBy = function(pluck, extremum) {
  return this.reduce(function(best, next) {
    var pair = [ pluck(next), next ];
    if (!best) {
       return pair;
    } else if (extremum.apply(null, [ best[0], pair[0] ]) == best[0]) {
       return best;
    } else {
       return pair;
    }
  },null)[1];
}

其作用与宣传的一样:

['albatross', 'dog', 'horse'].minBy( function(s) { return s.length; } )
// => "dog"

['albatross', 'dog', 'horse'].maxBy( function(s) { return s.length; } )
// => "albatross"

答案 1 :(得分:1)

文档中min_by的示例包含以下示例:

a = %w(albatross dog horse)
a.min_by {|x| x.length }   #=> "dog"

因此我们可以粗略地将其转换为JavaScript:

var arr = ['albatross', 'dog', 'horse'];

function minBy(arr) {
  var result = arr.map(function (el) { return el.length; });
  var min = Math.min.apply(null, result);
  return arr[result.indexOf(min)];
}

minBy(arr); // dog

max_by会改为使用Math.max.apply

function maxBy(arr) {
  var result = arr.map(function (el) {
    return el.length;
  });
  var min = Math.max.apply(null, result);
  return arr[result.indexOf(min)];
}

maxBy(arr); // albatross

您还可以修改数组原型以使其更具Rubyish。

if (!('minBy' in Array.prototype)) {
  Array.prototype.minBy = function (type) {
    var result = this.map(function (el) { return el[type]; });
    var min = Math.min.apply(null, result);
    return arr[result.indexOf(min)];    
  };
}

arr.minBy('length'); // dog

DEMO

答案 2 :(得分:1)

以与Ruby相同的方式使用它,即在数组上调用它:

Array.prototype.minBy = function(lambda) {
    var lambdaFn;
    if (typeof(lambda) === "function") {
        lambdaFn = lambda;
    } else {
        lambdaFn = function(x){
            return x[lambda];
        }
    }
    var mapped = this.map(lambdaFn); 
    var minValue = Math.min.apply(Math, mapped); 
    return this[mapped.indexOf(minValue)];
}

因此ruby示例变为:

['albatross', 'dog', 'horse'].minBy(function(x){return x.length })  // = 'dog'

或:

['albatross', 'dog', 'horse'].minBy("length") // = 'dog'

答案 3 :(得分:1)

我使用static Set<Character> dups3(String input) { Map<Character, Long> map = input.chars() .mapToObj(i -> (char)i) .collect(groupingBy(ch -> ch, counting())); return map.entrySet().stream() .filter(entry -> entry.getValue() > 1) .map(Map.Entry::getKey) .collect(toSet()); }

reduce

答案 4 :(得分:0)

Lodash同时包含minBymaxBy

来自文档:

var objects = [{ 'n': 1 }, { 'n': 2 }];

_.minBy(objects, function(o) { return o.n; }); // => { 'n': 1 }
// The `_.property` iteratee shorthand.
_.minBy(objects, 'n'); // => { 'n': 1 }

_.maxBy(objects, function(o) { return o.n; }); // => { 'n': 2 }