skip to Main Content

Given an array of objects with dynamic properties (except Id), what is the best way to replace the property keys with those from a map?

// For example, array of objects:
var records = [
  {"Id": "0035w000036m j7oAAA", "Business Phone": "(212) 842-5501"},
  {"Id": "0035w000036mj7oXXX", "Business Phone": "(212) 842-7777"}
];

// Map to pull replacement property from:
var colHeaderToFieldApiName = {"Business Phone": "Phone"};

// Desired output:
var result = [
  {"Id": "0035w000036mj7oAAA", "Phone": "(212) 842-5501"},
  {"Id": "0035w000036mj7oXXX", "Phone": "(212) 842-7777"}
];

Here’s what I have so far. It works, but just wondering if there’s a better way.

records.forEach (function (obj) {
  for (const prop in obi) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      const fieldApiName = colHeaderToFieldApiName [prop];
      if (fieldApiName) {
        obji[fieldApiName] = obj[prop];
        delete obi[prop];
      }
    }
  }
});

2

Answers


  1. In the following snippet all keys contained in newKeys will replace the given keys of the input array:

    var records = [
      {"Id": "0035w000036m j7oAAA", "Business Phone": "(212) 842-5501"},
      {"Id": "0035w000036mj7oXXX", "Business Phone": "(212) 842-7777"}
    ];
    
    // Map to pull replacement property from:
    var newKeys = {"Business Phone": "Phone"};
    
    // Desired output:
    var result = records.map(o=>
     Object.fromEntries( Object.entries(o).map(([k,v])=> [newKeys[k]??k,v] ) )
    );
    console.log(result);
    
    /* Output
    [
      {"Id": "0035w000036mj7oAAA", "Phone": "(212) 842-5501"},
      {"Id": "0035w000036mj7oXXX", "Phone": "(212) 842-7777"}
    ];
    */

    The key replacement works on the basis of the newKeys object: only the keys defined in that object will be replaced by their new names. All other keys will will remain the same.

    Login or Signup to reply.
  2. This is how I have done that in the past.

    It is not the fastest implementation, and it doesn’t matter unless you are talking about dozens of thousands of key remapping.

    If may or may not be the most clear way of doing this for some developers, but it sure is for me, so let me share anyway.

    It uses:

    • one key replacing function that is curried, because I like this way of function composition.

    • one map traversal over your list of objects applying this function.

    Here it is:

    const replacekeys = km => o => Object.fromEntries(
      Object.entries(o).map(([k, v]) => [k in km ? km[k] : k, v]))
    

    Usage:

    records.map(replacekeys(colHeaderToFieldApiName))
    

    Side notes:

    • You can use o.hasOwnProperty(k) in case you don’t want prototypal chain on key containment check;
    • If you don’t like the curried kinda functional style, you can easily change that to replacekeys = ([km, o]) => ... and then use it like records.map(o => replacekeys(colHeaderToFieldApiName, o))
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search