MandyM
MandyM

Reputation: 87

Javascript: how to easily replace object value with data from 2nd object?

I currently have a situation where I have 2 objects that look like this:

object a = {n: 15, b: 12, v: 10, h: 9} and so on.
object b = {1: e, 2: b, 3: z, 4: w} and so on.

I need to take the values from object b and use them to replace the values in object a. the result would look like:

object c = {n: e, b: b, v: z} etc.

One important thing is that if there are more items in object b than in object a, I still need them added on to the end of object c. so if there are 3 more items in object b, perhaps something like this {24: a, 25: y, 26:w} would happen at the end.

My first thought, of course, is a loop where I would iterate over each item in object a and replace the 'value' with that from object b. But I didn't know if there was a better way, especially with my concern about making sure that all of the items from object b are included in the new object.

Because of that concern, an alternative could be to replace the keys in object b with the keys in object a instead. that way if object a runs out, the last items in object b would't be excluded.

I've also tried:

Object.assign(a, b);

but that only works if the keys are the same, so that won't work. I need whatever happens to match index to index for the two objects.

If it matters, I can change object b to be anything I want as it's static. So, I could do:

object b = [e, b, z] etc. or
object b = {e: e, b: b, z: z}

Whatever makes it easiest to do.

I appreciate any thoughts anyone might have or if you can point me in the direction of a good post covering something like this. I'm currently scouring the internet and trying anything that sounds like it might work but so far, nothing has fit.

It's also worth noting that at this point I'm using pure vanilla JS so if there is a library or something that would make this super easy, I'm open to that.

Upvotes: 0

Views: 4085

Answers (4)

yqlim
yqlim

Reputation: 7080

var objectA = {n: 15, b: 12, v: 10, h: 9};
var objectB = {n: e, b: b, v: z, h: w, a: 1, c: 2};
var objectC = extend({}, objectA, objectB);

function extend(out){
    out = out || {};
    for (var i = 1, len = arguments.length; i < len; i++){
        var obj = arguments[i];
        if (!obj) continue;
        for (var key in obj){
            if (obj.hasOwnProperty(key))
                out[key] = (typeof obj[key] === 'object') ? extend(out[key], obj[key])
                                                          : obj[key];
        }
    }
    return out;
}

console.log(objectC);
// outputs {n: e, b: b, v: z, h: w, a: 1, c: 2}

It will throw error if e, b, z, w is not defined.

Values of objectA and objectB remain unchanged.

From extend({}, objectA, objectB), it gets the value from objectB to replace objectA, and then objectA to {} without changing the original value of objectA and objectB.

Note: You will need to change the keys in objectB to reflect keys in objectA instead of using 1, 2, 3... as keys.

Upvotes: 0

MandyM
MandyM

Reputation: 87

After doing a bit more searching and playing, something I read inspired me to make both objects into arrays instead and then join them into a map. Ended up being super easy. This was the result:

var a = ['a', 'b', 'c'];
var b = [1, 2, 3];
var map = {};
for(var i = 0; i < a.length; i += 1) {
  map[ a[i] ] = b[i];
}

console.log(map); // {a: 1, b: 2, c: 3}

Thanks for those who read it!

Upvotes: 0

Mμ.
Mμ.

Reputation: 8542

I am assuming that those letter values in object b are strings, but the example would also work on variables, you just have to remove the quotation marks.

My approach is: 1. Get all the keys in b and a 2. Create an empty object, Loop through the keys in b 3. Using the index of b, i can also get the index of a. This way, when we are iterating the 3rd time, i would be 2 and I can get the keys and values of a and b, which are v:10 and 3: 'z' respectively. Then I map the key of a to the value of b, so the result would be v: 'z'. 4. If b has more keys, just assign current key and value in b to c.

var a = {n: 15, b: 12, v: 10, h: 9};
var b = {1: 'e', 2: 'b', 3: 'z', 4: 'w', 24: 'a', 25: 'y', 26:'w'};

// get all the keys in a
let aKeys = Object.keys(a);

// get all the keys in b
let bKeys = Object.keys(b);

// acc is the accumulated object c, 
// at the beginning value of c is {}, it gets bigger as we loop through the keys of b
// i is the ith key in b
let c = bKeys.reduce((acc, _, i) => {
  // if a > b then put key value pair of b 
  if (i > aKeys.length - 1) {
    acc[bKeys[i]] = b[bKeys[i]];
  } else {
    acc[aKeys[i]] = b[bKeys[i]];  
  }
  return acc;
}, {});

console.log(c)

Upvotes: 1

Nick Wyman
Nick Wyman

Reputation: 1158

You could do something like the following

var objectA = {
  b: "test",
  a: "test2",
  c: "test3",
  d: "test4"
};

var objectB = ["new", "new2", "new3", "new4", "new5", "new6"];
var index = 0;

for (var prop in objectA) {
  if (objectA.hasOwnProperty(prop)) {
    objectA[prop] = objectB[index];
    index++;
  } 
}

for(index; index < objectB.length; index++) {
  objectA[index] = objectB[index];
}

Couple things though:

  1. The for..in loop is based on order of implementation. So whatever order the properties were added to the object will be the order of the loop.
  2. Functionality like what you are requesting seems like a code smell when viewed out of context. Typically you are not merging two objects like the way you are requesting. If you want to provide further context, a better solution might be offered up.

Upvotes: 1

Related Questions