【问题标题】:Weird behaviour of map and max in lodashlodash中地图和最大值的奇怪行为
【发布时间】:2013-10-29 11:03:30
【问题描述】:
var a = [ [1,2,3], [4,5,6], [7,8,9] ];
_.map( a, _.max );
// gives [3, -Infinity, -Infinity]

我已经在我的 Chrome 浏览器上测试了它,在 lodash 网站上。

上面的代码不应该返回 [3, 6, 9] 吗?

我可以用 forEach 得到正确的结果:

var a = [ [1,2,3], [4,5,6], [7,8,9] ];
var result = [];
_.forEach( a, function(arr) { result.push(_.max(arr)); } );

【问题讨论】:

    标签: javascript lodash


    【解决方案1】:

    总体结论

    我在 GitHub 上打开了一个问题:https://github.com/lodash/lodash/issues/379
    感谢jdalton,问题现已解决。示例:→jsFiddle

    详细信息(为什么结果“奇怪”?)

    我从未详细使用过 Lodash,但以下是我的研究:

    检索集合的最大值。如果集合为空或返回虚假-Infinity
    Lodash Documentation: _.max()

    测试_.max() 与每个小组各自完美地工作:

    _.max([1,2,3]);  // 3
    _.max([4,5,6]);  // 6
    _.max([7,8,9]);  // 9
    

    现在,我尝试在_.map()的回调函数中手动调用_.max()

    var a = [ [1,2,3], [4,5,6], [7,8,9] ];
    alert(_.map( a, function(val) {
        return _.max(val);
    }));
    

    工作正常!那么这与提供_.max() 作为第二个参数有什么区别呢?
    _.map()实际上向回调函数发送了3个参数:

    (值,索引|键,集合)。
    Lodash Documentation: _.map()

    现在考虑_.max()的第二个参数:

    2.[callback=identity] (Function|Object|string):每次迭代调用的函数。如果提供了属性名称或对象,它将是 分别用于创建“.pluck”或“.where”样式的回调。
    Lodash Documentation: _.max()

    结论: _.max() 也传递了_.map() 提供的第二个和第三个参数。第二个参数在这里很重要!为它传递真实值(例如整数!= 0)让函数返回-Infinity

    测试用例(→ jsFiddle):

    alert(_.max([1,2,3], 0)); // 3
    alert(_.max([1,2,3], 1)); // -Infinity
    alert(_.max([1,2,3], 2)); // -Infinity
    

    这来自源代码中执行的布尔检查: https://github.com/lodash/lodash/blob/f0f7eee963966516490eb11232c9e9b4c6d0cc6c/dist/lodash.js#L3431

    因为callback(第二个参数)是真值,所以直接跳转到else分支。在那里,callback 被重新分配如下(三元运算也将采用 else 分支):

    lodash.createCallback(callback, thisArg, 3);
    

    createCallback() 定义为 here。 它为我们的特定输入参数返回以下函数(这些是1, null, 3,详见_.max()):

    return function(object) {
      return object[func];
    };
    

    假设我们将其保存在一个名为 callback (→ jsFiddle) 的变量中:

    var callback = _.createCallback(1, null, 3);
    

    使用 object = 1(或 2、3 或 6 等)调用该函数会得到 undefined(这很明显)。

    回到_.max(),我们看到有一个循环将当前 值(来自回调函数)与初始/最后一个值进行比较,即设置为-Infinity在函数的开头。

    undefined > -Infinity 永远不会导致 true,因此-Infinity 将保持“最大值”。

    【讨论】:

    • 非常感谢您的解释!我不确定这是一个错误还是一个功能,所以我想在我在 lodash github 上提出这个问题之前确定一下。
    • @TPJ 不客气。该错误已由 jdalton 昨天修复:github.com/lodash/lodash/issues/379
    猜你喜欢
    • 2019-09-23
    • 2017-09-25
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    相关资源
    最近更新 更多