TheUnreal
TheUnreal

Reputation: 24462

Update array inside another array

I have a JSON array that represents a list of objects (people). every object (every person) has name attribute, image, and an array of numbers.

Example:

"people":[  
   {  
      "name":"nunu",
      "image":"image1",
      "numbers":{  
         "total":50,
         "vector":[  
            10,
            20,
            5,
            10,
            5
         ]
      }
   }
];

My goal is to update all vectors and append some calculation to each vector.

This is what I tried:

this.people = this.people.map((person) => {
      return person.numbers.vector.map((num) => {
        return Math.round(((num / divider) * 100) / 100);
      });
    });

The problem is that people is being replaced by the numbers in my vector and I lose the people data.

How I can update the vectors without making nay change to any other data?

Upvotes: 0

Views: 105

Answers (4)

Mr. Baudin
Mr. Baudin

Reputation: 2254

If you use the new spread operator and something like Babel this becomes trivial:

const source = {
  "people": [{
    "name": "nunu",
    "image": "image1",
    "numbers": {
      "total": 50,
      "vector": [
        10,
        20,
        5,
        10,
        5
      ]
    }
  }]
};

const newSource = {
  ...source,
  people: source.people.map(person => {
    return {
      ...person,
      numbers: {
        ...person.numbers,
        vector: person.numbers.vector.map(n => Math.round(((n / 2) * 100) / 100))
      }
    }
  })
};

Here is more on the spread operator.

As a side note, using the spread operator creates a new object and using map creates a new array. This way you will always have a new object and can't change the old one. Using const with this type of code is also a good practice.

Upvotes: 0

dhilt
dhilt

Reputation: 20744

Due to .map() specification it creates a new array, to process top-level list use .forEach() instead:

this.people.forEach(person => 
  person.numbers.vector = person.numbers.vector.map(num =>
    Math.round(((num / divider) * 100) / 100)
  );
);

Upvotes: 1

Artem Kolodko
Artem Kolodko

Reputation: 409

Try using spread operator to update person object and save all data. For example, calculate total value as sum of nums:

 this.people = this.people.map((person) => {
   let total = person.numbers.vector.reduce((prevNum, nextNum) => {
     return prevNum + nextNum;
   });

   return {
      ...person,
      numbers: {
         ...person.numbers,
         total
      }

  }
});

At the same way you can change vector values, for example

Upvotes: 0

Shardj
Shardj

Reputation: 1969

people = people.map((person) => {
    person.numbers.vector =  person.numbers.vector.map((num) => {
        return Math.round(((num / divider) * 100) / 100);
    });
    return person;
});

You were returning the vector as the value for person, you need to change the value of vector then return person instead.

Upvotes: 0

Related Questions