简体   繁体   中英

Javascript how to push a new element from an initial array to each array inside an array of arrays at the same index?

I want to add new property to an array from another array using indexes of both.

For example, lets say I have the following array:

initArray = [
  { name: 'John', family: 'Doe'},
  { name: 'Joanna', family: 'Doe'}
];

And the array that I want to take from it and push it into initArray :

genderArray = [
  { gender: 'Male' },
  { gender: 'Female' }
];

What I need is a final array that be like:

initArray = [
  { name: 'John', family: 'Doe', gender: 'Male'},
  { name: 'Joanna', family: 'Doe', gender: 'Female'}
];

I tried the following:

ngOnInit() {
  Object.keys(this.genderArray).forEach((idx) => {
    console.log(this.initArray)
    this.initArray[idx].push(this.genderArray)
  });

  console.log(this.initArray)
}

But it returned an error of:

Error: _this.initArray[idx].push is not a function

Here is a stackblitz .

First, you should not push to initArray : you do not add elements to initArray , but instead add a property to each of its elements.

One possible way to do that:

Object.assign(this.initArray[idx], this.genderArray[idx]);

... or, if for some reason you want to create a completely new array of new 'enriched' objects, instead of modifying objects directly:

this.initArray[idx] = {...this.initArray[idx], ...this.genderArray[idx]};

Second, do not use Object.keys() to go through an array: use either forEach() if you do all the transformations inside the function or map , if you return a new element and want to have a new array in the end.

So your function might look like that:

ngOnInit() {
  this.genderArray.forEach((element, index) => {
    Object.assign(this.initArray[index], element);
  });

  console.log(this.initArray)
}

... or...

ngOnInit() {
  this.initArray = this.initArray.map((element, index) => {
     { ...element, ...this.genderArray[index] }
  });

  console.log(this.initArray)
}

Personally, I always find code 'x = x.map(transformer())` highly suspicious (if one reassign anyway, why not use forEach?), but it's up to implementation style choices.


If there's more than property in the elements of an array to be 'mixed', but you only want to take one, you can either go direct:

Object.assign(this.initArray[idx], { gender: this.genderArray[idx].gender });

... use destructuring in assignment:

const { gender } = this.genderArray[idx]; 
Object.assign(this.initArray[idx], { gender });

... or just bite the bullet and do assignment straight as we did in the good old syntax-sugar-free days:

this.initArray[idx].gender = this.genderArray[idx].gender;

In this particular case the last one looks like the best approach actually. Its disadvantage is having to repeat the property name, but that might also come handy if you want the props to be named differently in source and target arrays.

You're actually trying to "merge" objects in two arrays.

There are many ways to implement this, but I think the clearest one is with the Array.map and Object.assign functions:

 const initArray = [ { name: 'John', family: 'Doe'}, { name: 'Joanna', family: 'Doe'} ]; const genderArray = [ { gender: 'Male' }, { gender: 'Female' } ]; const ans = initArray.map((person, index) => { const genderedPerson = Object.assign({}, person, genderArray[index]); return genderedPerson; }); console.log(ans);

  • Array.map iterates an array and modifies its elements.
  • Object.assign extends an object, adding it additional properties from another object(s).

The problem is that you're trying to use array.push() on an object, which doesn't work.

Instead, you could use a for loop to go through the array, and simply add a 'gender' category to that index by assigning a value to it, namely the gender at that index in the other array:

 initArray = [ { name: 'John', family: 'Doe'}, { name: 'Joanna', family: 'Doe'} ]; genderArray = [ { gender: 'Male' }, { gender: 'Female' } ]; for (var i = 0; i < initArray.length; i++) { initArray[i].gender = genderArray[i].gender; } console.log(initArray);

Alternatively, you could use array.forEach() :

 initArray = [ { name: 'John', family: 'Doe'}, { name: 'Joanna', family: 'Doe'} ]; genderArray = [ { gender: 'Male' }, { gender: 'Female' } ]; initArray.forEach(addGender); function addGender(_, i) { initArray[i].gender = genderArray[i].gender; } console.log(initArray);

You can merge two arrays by reduce method using ... spread operator:

const result = initArray.reduce((a, c, i) => {
   a.push({...c, ...genderArray[i]})
   return a;
},[])

or one line version:

const result = initArray.reduce((a, c, i) => (a.push({...c, ...genderArray[i]}), a),[])

An example:

 let initArray = [ { name: 'John', family: 'Doe'}, { name: 'Joanna', family: 'Doe'} ]; let genderArray = [ { gender: 'Male' }, { gender: 'Female' } ]; const result = initArray.reduce((a, c, i) => { a.push({...c, ...genderArray[i]}) return a; },[]) console.log(result)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM