最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Apply _.set with _.each in lodash - Stack Overflow

programmeradmin1浏览0评论

I want to be able to set a property on all objects inside of an array like this:

var items = [{ a: 1 }, { a: 2 }, { a: 3 }];

_.each(items, set('a', 4));

// result should be [{ a: 4 }, { a: 4 }, { a: 4 }]

I tried to acplish this by using _.rearg on _.set to change the parameter that takes the object to the last one like this:

var set = _.rearg(_.set, [2, 0, 1]);

However, I cannot get _.curry to work on top of calling _.rearg.

var set = _.curry(_.rearg(_.set, [2, 0, 1]));

set('a', 3, { a: 4 })
// returns Object {a: 3} correctly

set('a', 3)
//returns undefined, should be a function

So the desired result of being able to call it like this set('a', 3)({ a: 2 }) throws an error because it does not return a function.

How do I acplish this using lodash? I must be missing something.

I want to be able to set a property on all objects inside of an array like this:

var items = [{ a: 1 }, { a: 2 }, { a: 3 }];

_.each(items, set('a', 4));

// result should be [{ a: 4 }, { a: 4 }, { a: 4 }]

I tried to acplish this by using _.rearg on _.set to change the parameter that takes the object to the last one like this:

var set = _.rearg(_.set, [2, 0, 1]);

However, I cannot get _.curry to work on top of calling _.rearg.

var set = _.curry(_.rearg(_.set, [2, 0, 1]));

set('a', 3, { a: 4 })
// returns Object {a: 3} correctly

set('a', 3)
//returns undefined, should be a function

So the desired result of being able to call it like this set('a', 3)({ a: 2 }) throws an error because it does not return a function.

How do I acplish this using lodash? I must be missing something.

Share Improve this question asked Feb 12, 2016 at 20:14 DerekMT12DerekMT12 1,35911 silver badges15 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 1

The _.curry function accepts an argument arity that you should probably set to 3:

_.curry(func, [arity=func.length])

Creates a function that accepts arguments of func and either invokes func returning its result, if at least arity number of arguments have been provided, or returns a function that accepts the remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.

The result from _.rearg has a length value of zero but the underlying function requires three parameters, so you will need to specify that manually:

var set = _.curry( _.rearg(_.set, [2, 0, 1]), 3 );

Here's a live demo: http://codepen.io/anon/pen/qbgmPq

if your items is

var items = [{ a: 1 }, { a: 2 }, { a: 3 }];

then for lodash _.each and _.set, it would be like this

_.each(items, function(item){
    _.set(item, 'a', 4);
});

what you are trying to do is, looking up a property 4 on item a, where it doesn't know when a is or 4 is. hope it helps.

Iterating through the list of items and using _.set on each item works.

_.map(items,function(item){_.set(item,'a',5)});

or

_.each(items,function(item){_.set(item,'a',5)});

Codepen

The problem with rearg() es when you have to read your code six months later - deciphering the argument positions is cumbersome. Combining unary() and partialRight() gives a much clearer intent:

_.each(items, _.unary(_.partialRight(_.set, 'a', 4)));

I used _.partial

const _ = require('lodash')

const __ = {
    each: bindEach,
    set: bindSet,
    setEach: bindSetEach,
}

function bindArg(func, ...bindArgs) {
    return _.partial(func, _, ...bindArgs)
}

function bindEach(...eachArgs) {
    return bindArg(_.each, ...eachArgs)
}

function bindSet(...setArgs) {
    return bindArg(_.set, ...setArgs)
}

function bindSetEach(...setArgs) {
    return bindEach(bindSet(...setArgs))
}

module.exports = __
const __ = require('./bindArg')

test('setEach', () => {
    expect(__.setEach('c', 3)([{a: 1}, {b: 2}])).toEqual([{a: 1, c: 3}, {b: 2, c: 3}])
})
发布评论

评论列表(0)

  1. 暂无评论