_.invoke方法如何在Lodash中运行?

时间:2015-03-05 22:11:52

标签: javascript underscore.js lodash

背景

关于invoke方法的文档,我读到:

  

在集合中的每个元素上调用methodName命名的方法,返回每个调用方法的结果数组

因此,我假设以下代码是同义词,但事实并非如此:

_.map(items, function(item) {
    return _.omit(item, 'fieldName');
})

_.invoke(items, _.omit, 'fieldName');

在这种情况下,invoke方法会生成一个字符串数组,而map方法会返回从每个项目中删除fieldName的项目数组。

问题

  • 如何使用invoke方法获得与map函数相同的结果?
  • 为什么invoke在这种特定情况下返回字符串数组?

var items = [{id:1, name:'foo'}, 
             {id:2, name:'bar'}, 
             {id:3, name:'baz'}, 
             {id:4, name:'qux'}];

console.log(
    _.invoke(items, _.omit, 'id')
);

console.log(
    _.map(items, function(item) {
        return _.omit(item, 'id');
    })
);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.3.1/lodash.min.js"></script>

4 个答案:

答案 0 :(得分:8)

var result = _.invoke(items, fn, extraArgs)

相当于

var result = [];
for (var i=0; i<items.length; i++) {
  result.push( fn.apply(items[i], extraArgs) );
}

因此,如果您想要与地图相同的结果,那么它将是

_.invoke(items, function() {
  return _.omit(this, 'id');
})

唯一的区别是item不是函数的参数,而是需要使用this,因为函数应用于项目

答案 1 :(得分:7)

请务必记下您正在使用的lodash版本。

v4.11.1在对集合进行操作时使用_.invokeMap

_.invokeMap([1,2,3], function () {
    console.log(this)
})

答案 2 :(得分:2)

invoke将该函数称为实例方法。

例如,

[
(new Date()).toString(),
(new Date()).toString(),
(new Date()).toString()
]

可以改写为:

_.invoke([new Date(), new Date(), new Date()], 'toString')

它大致类似于map,其中map传递了一个函数,但invoke传递了一个实例的方法。

如果你真的想让invoke在这里为你工作,那么我想你可以这样做:

var items = [{id:1, name:'foo'}, 
             {id:2, name:'bar'}, 
             {id:3, name:'baz'}, 
             {id:4, name:'qux'}];
_.invoke(items, function() { return _.omit(this, 'id') });
// => [Object {name="foo"}, Object {name="bar"}, Object {name="baz"}, Object {name="qux"}]

但你不应该这样做。只需使用map

答案 3 :(得分:1)

Joe Frambach所述,map()更适合此。

var collection = [
    { id:1, name:'foo' },
    { id:2, name:'bar' },
    { id:3, name:'baz' },
    { id:4, name:'qux' }
];

_.map(collection, _.ary(_.partialRight(_.omit, 'id'), 1));
// → 
// [
//   { name: 'foo' },
//   { name: 'bar' },
//   { name: 'baz' },
//   { name: 'qux' }
// ]