【问题标题】:Why can't I chain this series of lodash calls?为什么我不能链接这一系列的 lodash 调用?
【发布时间】:2014-03-02 20:12:36
【问题描述】:

这段代码:

  _(gameState.loot)
  .pick((value, key) -> key isnt "pickUpAnimations")
  .filter ((d) -> _.isArray (d))
  .reduce ((sum, d) -> sum.concat (d))

给我这个错误:

TypeError: 'undefined' is not a function (evaluating '(function(d) {

而这段代码运行良好:

  removedAnimations = _.pick(gameState.loot, (value, key) -> key isnt "pickUpAnimations")
  removedAnimations = _.filter removedAnimations, ((d) -> _.isArray (d))
  removedAnimations = _.reduce removedAnimations, ((sum, d) -> sum.concat (d))
  removedAnimations

在我看来,这些似乎应该做同样的事情。 gameState.loot 的架构如下所示:

loot: {
  ttl: 6000
  slowBlinkWhenTtlLessThanPercent: 60
  fastBlinkWhenTtlLessThanPercent: 30
  resurrections: []
  gold: []
  health: []
  equipment: []
  pickUpAnimations: []
}

顺便说一句,这是从第一个示例生成的 javascript:

return _(gameState.loot).pick(function(value, key) {
  return key !== "pickUpAnimations";
}).filter((function(d) {
  return _.isArray(d);
}).reduce((function(sum, d) {
  return sum.concat(d);
})));

我尝试了@Blender 的建议:

  _(gameState.loot)
    .pick (value, key) -> key isnt "pickUpAnimations"
    .filter (d) -> _.isArray (d)
    .reduce (sum, d) -> sum.concat (d)

但这给了我这个错误:

>> TypeError: 'undefined' is not a function (evaluating '"pickUpAnimations".filter(function(d) {

下面是 javascript 的样子:

return _(gameState.loot).pick(function(value, key) {
  return key !== "pickUpAnimations".filter(function(d) {
    return _.isArray(d.reduce(function(sum, d) {
      return sum.concat(d);
    }));
  });
});

【问题讨论】:

标签: javascript coffeescript underscore.js lodash


【解决方案1】:

这是生成的缩进效果更好的 JavaScript:

_(gameState.loot).pick(function(value, key) {
    return key !== "pickUpAnimations";
}).filter(
    (function(d) {
        return _.isArray(d);
    }).reduce((function(sum, d) {
        return sum.concat(d);
    }))
);

如您所见,.filter (....filter(... 并不相同。两种可能的修复方法:

  1. 删除方法名称和左括号之间的空格:

    _(gameState.loot)
        .pick((value, key) -> key isnt "pickUpAnimations")
        .filter((d) -> _.isArray (d))
        .reduce((sum, d) -> sum.concat (d))
    
  2. 完全去掉括号:

    _(gameState.loot)
        .pick (value, key) -> key isnt "pickUpAnimations"
        .filter (d) -> _.isArray (d)
        .reduce (sum, d) -> sum.concat (d)
    

你也可以去掉匿名函数调用_.isArray

    _(gameState.loot)
        .pick (value, key) -> key isnt "pickUpAnimations"
        .filter _.isArray
        .reduce (sum, d) -> sum.concat (d)

【讨论】:

  • 我正在查看生成的代码与我在上面评论中的内容相比,是的,这确实是问题。
  • 这个错误对我来说是不同的。请参阅我的问题中的编辑。
  • 感谢您的帮助并查看了 javascript,我意识到我并没有像我想象的那样使用 Coffeescript 1.7.1。我不得不更新我的 grunt-contrib-coffeescript 插件。
  • @tieTYT 请注意,如果您运行的是 CoffeeScript 1.7,则建议的修复都不是必需的。您的原始代码编译得很好。
  • @AaronDufour 我认为应该这样做。这就是让我非常困惑的地方。我有最新的咖啡脚本,但显然我必须升级 grunt-contrib-coffee 才能在我的 grunt 项目中使用最新的。
【解决方案2】:

coffeescript 的黑暗面:

_(gameState.loot).pick(function(value, key) {
  return key !== "pickUpAnimations";
}).filter((function(d) {
  return _.isArray(d);
}).reduce((function(sum, d) {
  return sum.concat(d);
})));

在过滤器回调之前注意额外的(。正在发生的事情是你在打电话:

(function(d) { return _.isArray(d); }).reduce(...

这会失败。修好你的卷发,你就可以开始了。

【讨论】:

    猜你喜欢
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 2015-12-13
    • 2019-08-31
    • 1970-01-01
    • 2018-04-21
    • 2018-02-28
    相关资源
    最近更新 更多