简体   繁体   中英

lodash mapping of keys

I am just getting my head around lodash, so the answer to this question is probably straightforward.

Say I have the following array:

var arr = [{ a: 2, b: 3, c: 4 }, { a: 1, b: 4, c: 2 }];

I'd like to rename some keys (for all objects) and drop another, to give the following new array:

var newArr = [{ x: 2, y: 4 }, { x: 1, y: 2 }];

So, that's renaming a, c to x, y, and dropping b.

What's the neatest way to do this with lodash? I think that mapKeys should be employed but that requires an object as input rather than a collection.

This is a similar problem to that posted at lodash multidimensional pluck .

Just use map :

_.map(arr, function(obj) { return { x: obj.a, y: obj.c } });

Or, as Vohuman notes, you could simply use the native map function (if IE8 support isn't a concern):

arr.map(function(obj) { return { x: obj.a, y: obj.c } });

With ES6 you can be really concise using arrow functions , parameter destructuring , and an implicit return:

arr.map(({a, c}) => ({ x: a, y: c }));

I am not sure if _.mapKeys() will remove unwanted keys from object. Below I prepared more flexible solution for your task. It can be converted to Lodash function with _.mixin .

var arr = [{ a: 2, b: 3, c: 4 }, { a: 1, b: 4, c: 2 }];

// mapping keys (if not presented - will be removed)
var keysMap = {
    a: 'x',
    c: 'y'
};

var newArr = arr.map(function(a){
    var o = {};
    Object.keys(a).forEach(function(k){
        if(Object.keys(keysMap).indexOf(k) >= 0){
            o[keysMap[k]] = a[k];
        }
    });
    return o;
});

// newArr: [{x: 2, y: 4}, {x: 1, y: 2}]

EDIT:

Lodash solution (should be more readable):

var arr = [{ a: 2, b: 3, c: 4 }, { a: 1, b: 4, c: 2 }];

_.mixin({
    mapObject: function(o, keysMap){
        var n = {};
        _.each(keysMap, function(v, k){
            if(!!o[k]){
                n[v] = o[k];
            }
        });
        return n;
    }
});

var keysMap = {
    a: 'x',
    c: 'y'
};

var newArr = _.map(arr, function(a){
    return _.mapObject(a, keysMap);
});

Here's an approach that uses map() , and pick() :

_.map(arr, _.ary(_.partialRight(_.pick, 'a', 'b'), 1));

The partialRight() call makes a callback function that'll create new objects with only the given property names — 'a' and 'b' are partially-applied to pick() .

The ary() function makes sure that only one argument is ever passed to the callback. We need this because map() will supply several arguments, and our callback function will only work with the item itself as an argument.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM