17

I have

var tab = {
abc:1,
def:40,
xyz: 50
}

I want to change the name of abc,def, xyz to something else, is it possible?

I tried

const test = Object.keys(tab).map(key => {
  if (key === 'abc') {
    return [
      a_b_c: tab[key]
    ]
  }
});

console.log(test);

I got many undefined keys.

8
  • Sure you do - your map callback only returns anything when key === 'abc', and will return undefined else. What did you expect? Commented May 8, 2017 at 3:44
  • 1
    Actually that should throw a syntax error. Array literals don't have properties. Commented May 8, 2017 at 3:45
  • 1
    Is the question "How do I rename object properties?", or "How do I rename object properties with Object.keys()?" Anyway, you can't rename a property, you have to add a new property and delete the old one. Or build a new object with the key names that you want. Commented May 8, 2017 at 3:51
  • @nnnnnn I don;'t know, as long as it worked, I mentioned object.keys() because that's what in my mind first. Basically I want to normalize or change the object key's names. Commented May 8, 2017 at 3:52
  • 1
    Renaming object keys. By the way, what if another property already exists with the new name? Commented May 8, 2017 at 3:55

11 Answers 11

18

Here is the full code for replacing keys based on object that maps the values to replace:

const tab = {abc: 1, def: 40, xyz: 50};
const replacements = {'abc': 'a_b_c', 'def': 'd_e_f'};

let replacedItems = Object.keys(tab).map((key) => {
  const newKey = replacements[key] || key;
  return { [newKey] : tab[key] };
});

This will output an array with three objects where keys are replaced. If you want to create a new object out of them, just:

const newTab = replacedItems.reduce((a, b) => Object.assign({}, a, b));

This outputs: {"a_b_c": 1, "d_e_f": 40, "xyz": 50}

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

1 Comment

Object.assign({}, ...replacedItems) should do as well. And don't forget to pass an initial argument to reduce!
6

Here's how I solved it. I used a map to map between existing key and new key. Just substitute the map with whatever new values you need. Finally remove old keys from the object using omit.

var tab = {
  abc:1,
  def:40,
  xyz: 50
}

var map = {
    abc : "newabc",
    def : "newdef",
    xyz : "newxyz"
}


_.each(tab, function(value, key) {
    key = map[key] || key;
    tab[key] = value;
});


console.log(_.omit(tab, Object.keys(map)));

1 Comment

what if u dont know the abc ,def , xyz in map?
6

With lodash mapKeys function its quite easy to transform object keys.

let tab = {
  abc: 1,
  def: 40,
  xyz: 50
}

const map = {
  abc: "newabc",
  def: "newdef",
  xyz: "newxyz"
}

// Change keys
_.mapKeys(tab, (value, key) => {
  return map[value];
});

// -> { newabc: 1, newdef: 40, newxyz: 50 }

1 Comment

I think that it should be: return map[key]
5

Here is a way to do it with deconstructing assignment and arrow functions.

const rename = (({abc: a_b_c, ...rest}) => ({a_b_c, ...rest}))
console.log(rename({abc: 1, def: 2}))
// { "a_b_c": 1, "def": 2 }

Comments

3

UPDATE: Sorry for the syntax errors; corrected and verified in browser console.

Shortest way I've found so far:

let tab = {abc: 1, def: 40, xyz: 50};

const {abc: a_b_c, def: d_e_f, ...rest} = tab;
tab = {a_b_c, d_e_f, ...rest}  
// { "a_b_c": 1, "d_e_f": 40, "xyz": 50}

3 Comments

I tried this code and it doesn't work, can you provide a REPL? Thanks!
change const tab to let tab. You didn't state the error you were getting.
It would be more beneficial to have an embedded working example. The current error when copying and pasting this code into one is: "Unexpected token (3:14)"
2

That's easy with lodash.

import { mapKeys } from 'lodash';    

const tab = {
    abc: 1,
    def: 40,
    xyz: 50
};

const test = mapKeys(tab, (value, key) => {
    if (key === 'abc') return 'a_b_c';
    return key;
});

1 Comment

1

A really easy way to change the keys dynamically without having to map the new key values could work like this :

const tab = { abc: 1, def: 40, xyz: 50 };
const changeString = (s) => s.split('').join('_');

Object.entries(tab).reduce((acc, [k, v]) => ({ ...acc, [changeString(k)]: v }), {})

// Output: {a_b_c: 1, d_e_f: 40, x_y_z: 50}

It uses Object.entries but you can easily swap it over to Object.keys like this:

Object.keys(tab).reduce((acc, k) => ({ ...acc, [changeString(k)]: tab[k] }), {})

Advanced: Nested objects

If you have nested objects and want to cycle through all the keys, you could try this:

const changeString = (s) => s.split('').join('_');
const isArray = (a) => Array.isArray(a);
const isObject = (o) => o === Object(o) && !isArray(o) && typeof o !== 'function';

const keyChanger = (o) => {
  if (isObject(o)) {
    return Object.entries(o).reduce((acc, [k, v]) => ({ ...acc, [changeString(k)]: keyChanger(v) }), {})

  } else if (isArray(o)) {
    return o.map((i) => keyChanger(i));
  }

  return o;
};

And you call it by simply doing this:

const tab2 = { abc: 1, def: 40, xyz: { hij: 12, klm: [{ nop: 43 }, { qrs: 65 }]}}

keyChanger(tab2)

// Output: { a_b_c: 1, d_e_f: 40, x_y_z: { h_i_j: 12, k_l_m: [{ n_o_p: 43 }, { q_r_s: 65 }]}}

Comments

1

const countries = [
    {"id": 1, "name": "Afghanistan"},
    {"id": 2, "name": "Albania"},
    {"id": 3, "name": "Algeria"},
    {"id": 4, "name": "American Samoa"}
];
const transformed = countries.map(({ id, name }) => ({ label: id, value: name }));
console.log(transformed);

Comments

0

You can add the new key and delete the old one.

var tab = {
abc:1,
def:40,
xyz: 50
}

    var key = 'abc'
    console.log(key)
    tab['a_b_c'] = tab[key]
    delete tab[key]
    
 
console.log(tab);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

2 Comments

Why loop at all?
Got your, it was not needed since OP was checking for a single value, can just directly edit it. Thanks, I missed that
0

you can use ES6 destructuring for it. For example, you can do something like this:

let sample = {a:1,b:2,c:3}
let {a:pippo,...rest} = sample
sample={pippo,...rest}

Comments

-1

hope this will help

initial data:

let tab = {
    abc: 1,
    def: 40,
    xyz: 50
};

new key mappings:

let newKeyMappings = {
    abc: 'cab',
    def: 'fed',
    xyz: 'zyx'
};

mapping values with new keys

let mapped = Object.keys(tab).map(oldKey=> {
    let newKey = newKeyMappings[oldKey];
    let result ={};
    result[newKey]=tab[oldKey];
    return result;
});

since mapped contains array of mapped object apply reduce operator

let result = mapped.reduce((result, item)=> {
    let key = Object.keys(item)[0];
    result[key] = item[key];
    return result;
}, {});

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.