5

I'm attempting to modify an array of objects with lodash, and struggling a bit. I would like to take the array below and change the keys in the objects.

Here is my source array:

[
    {
        "id": "AD",
        "name": "Andorra",
        "currency": "EUR",
        "timezone": "Europe/Andorra",
        "links": [
            {
                "rel": "self",
                "href": "http://localhost:8000/api/countries/AD"
            },
            {
                "rel": "country.currency",
                "href": "http://localhost:8000/api/currencies/EUR"
            }
        ]
    },
    {
        "id": "AE",
        "name": "United Arab Emirates",
        "currency": "AED",
        "timezone": "Asia/Dubai",
        "links": [
            {
                "rel": "self",
                "href": "http://localhost:8000/api/countries/AE"
            },
            {
                "rel": "country.currency",
                "href": "http://localhost:8000/api/currencies/AED"
            }
        ]
    },
    ...
    ]

I would like this to result in:

[
    {
        "value": "AD",
        "title": "Andorra",
        "currency": "EUR",
        "timezone": "Europe/Andorra",
        "links": [
            {
                "rel": "self",
                "href": "http://localhost:8000/api/countries/AD"
            },
            {
                "rel": "country.currency",
                "href": "http://localhost:8000/api/currencies/EUR"
            }
        ]
    },
    {
        "value": "AE",
        "title": "United Arab Emirates",
        "currency": "AED",
        "timezone": "Asia/Dubai",
        "links": [
            {
                "rel": "self",
                "href": "http://localhost:8000/api/countries/AE"
            },
            {
                "rel": "country.currency",
                "href": "http://localhost:8000/api/currencies/AED"
            }
        ]
    },
    ...
    ]

Note that the first two keys are renamed. I know I can use _.mapKeys to modify the keys, however I'm not sure how to iterate the array in the best way to do this.

Any suggestions would be much appreciated.

2
  • Iterate with map and run mapKeys on each iteration? Commented Oct 3, 2017 at 21:55
  • great suggestions, thanks everyone Commented Oct 3, 2017 at 22:25

3 Answers 3

6

Iterate using Array#map (or lodash's _.map()), and use Object#assign (or _.assign()) to generate a new object with the change key.

Assign will meld an object with new keys with the respective values from the original object, and the original object without the keys you want to replace using _.omit().

var data = [{"id":"AD","name":"Andorra","currency":"EUR","timezone":"Europe/Andorra","links":[{"rel":"self","href":"http://localhost:8000/api/countries/AD"},{"rel":"country.currency","href":"http://localhost:8000/api/currencies/EUR"}]},{"id":"AE","name":"United Arab Emirates","currency":"AED","timezone":"Asia/Dubai","links":[{"rel":"self","href":"http://localhost:8000/api/countries/AE"},{"rel":"country.currency","href":"http://localhost:8000/api/currencies/AED"}]}];

var result = data.map(function(o) {
  return Object.assign({
    value: o.id,
    title: o.name
  }, _.omit(o, 'id', 'name'));
});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Another option is to use _.mapKeys() to change the key names:

var data = [{"id":"AD","name":"Andorra","currency":"EUR","timezone":"Europe/Andorra","links":[{"rel":"self","href":"http://localhost:8000/api/countries/AD"},{"rel":"country.currency","href":"http://localhost:8000/api/currencies/EUR"}]},{"id":"AE","name":"United Arab Emirates","currency":"AED","timezone":"Asia/Dubai","links":[{"rel":"self","href":"http://localhost:8000/api/countries/AE"},{"rel":"country.currency","href":"http://localhost:8000/api/currencies/AED"}]}];

var keys = { id: 'value', name: 'title' };

var result = data.map(function(o) {
  return _.mapKeys(o, function(v, k) {
    return k in keys ? keys[k] : k;
  });
});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

2

I prefer not to change the original data so this is what I would do:

const thing = [{id:"AD",name:"Andorra",currency:"EUR",timezone:"Europe/Andorra",links:[{rel:"self",href:"http://localhost:8000/api/countries/AD"},{rel:"country.currency",href:"http://localhost:8000/api/currencies/EUR"}]},{id:"AE",name:"United Arab Emirates",currency:"AED",timezone:"Asia/Dubai",links:[{rel:"self",href:"http://localhost:8000/api/countries/AE"},{rel:"country.currency",href:"http://localhost:8000/api/currencies/AED"}]}];

const newThing = [];

thing.map( item => {
    newThing.push(
        _.mapKeys( item, ( value, key ) => {
            let newKey = key;
            if( key === 'id' ) {
                newKey = 'value';
            }

            if( key === 'name' ) {
                newKey = 'title';
            }

            return newKey;
        })
    )
});

console.log( newThing );

1 Comment

Why you define a new List(newThing)? map return a new list itself
1

You can use _.map and create a new object, change the keys based on the condition and return the new object.

var obj = [{
  "id": "AD",
  "name": "Andorra",
  "currency": "EUR",
  "timezone": "Europe/Andorra",
  "links": [{
    "rel": "self",
    "href": "http://localhost:8000/api/countries/AD"
  }, {
    "rel": "country.currency",
    "href": "http://localhost:8000/api/currencies/EUR"
  }]
}, {
  "id": "AE",
  "name": "United Arab Emirates",
  "currency": "AED",
  "timezone": "Asia/Dubai",
  "links": [{
    "rel": "self",
    "href": "http://localhost:8000/api/countries/AE"
  }, {
    "rel": "country.currency",
    "href": "http://localhost:8000/api/currencies/AED"
  }]
}];

var updatedObj = _.map(obj, function(currObj, index) {
    var newObj = {};
    
    Object.keys(currObj).forEach(function(key) {
        if(key === 'id') {
    	     newObj.value = currObj[key];
    	  } else if(key === 'name') {
           newObj.name = currObj[key];
        } else {
           newObj[key] = currObj[key];
        }
    });
    return newObj;
});

console.log(updatedObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.