15

How should I replace the key strings in a Javascript key:value hash map (as an object)?

This is what I have so far:

var hashmap = {"aaa":"foo", "bbb":"bar"};
console.log("before:");
console.log(hashmap);

Object.keys(hashmap).forEach(function(key){
   key = key + "xxx";
   console.log("changing:");
   console.log(key);
});

console.log("after:");
console.log(hashmap);

See it running in this jsbin.

The "before" and "after" hashmaps are the same, so the forEach seems to be in a different scope. How can I fix it? Perhaps there are better ways of doing this?

1

5 Answers 5

29

It has nothing to do with scope. key is just a local variable, it's not an alias for the actual object key, so assigning it doesn't change the object.

Object.keys(hashmap).forEach(function(key) {
  var newkey = key + "xxx";
  hashmap[newkey] = hashmap[key];
  delete hashmap[key];
});
Sign up to request clarification or add additional context in comments.

2 Comments

Note that this only works if all the new keys are different from the old key, like in this example, or else the key would be deleted entirely.
@HaoQiLi Quite true. A safer algorithm would involve copying the object to a new object, then copying back. Feel free to post answer like that.
4

if keys order is important you can use:

const clone = Object.fromEntries(
  Object.entries(o).map(([o_key, o_val]) => {
    if (o_key === key) return [newKey, o_val];
    return [o_key, o_val];
  })
);

this will create an object with the new key in the same place where the old one was.

Comments

2

Update

This way is better, in my opinion.

const hashmap = { aaa: 'foo', bbb: 'bar' };

const newHashmap = Object.fromEntries(
  Object
    .entries(hashmap)
    .map(([k, v]) => [`${k}xxx`, v]),
);

console.log(newHashmap);
// { aaaxxx: 'foo', bbbxxx: 'bar' }

Previous

You can use Array.prototype.reduce().

const hashmap = { aaa: 'foo', bbb: 'bar' };

const newHashmap = Object.entries(hashmap).reduce((acc, [key, value]) => ({
  ...acc,
  [`${key}xxx`]: value,
}), {});

console.log(newHashmap);
// { aaaxxx: 'foo', bbbxxx: 'bar' }

Comments

1

You are just changing the copy of the object's keys, so the original object won't be changed. You can create an new object to hold the new keys, like this:

var hashmap = {"aaa":"foo", "bbb":"bar"};
console.log("before:");
console.log(hashmap);

var newHashmap = {};
Object.keys(hashmap).forEach(function(key){
    var value = hashmap[key];

    key = key + "xxx";
    console.log("changing:");
    console.log(key);

    newHashmap[key] = value;
});

console.log("after:");
console.log(newHashmap);

Comments

0

The function takes as an argument the original map and returns a new one with the keys altered. The call of the mapT(m) just returns the transformed map with the new keys.

function mapT(map){
    const x = new Map();
    for (const [k, v] of map) {
      x.set(k+ "xxx", v);
    }    
    return x;
}

Simple call : var new_map = mapT(mapA);

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.