1

Say I have an array of objects:

const peopleArray = [
{
 'date': '3/1',
 'people': 0
},
{
 'date: '3/2',
 'people': 5
},
{
 'date: '3/3',
 'people': 8
},
...
];

I'm trying to draw a chart showing daily difference between the number of people, so I need the following array of objects:

[{ 
 'date': '3/1,
 'diff': 0 // Shows 0 the first day.
},
{
 'date': '3/2',
 'diff': 5 // 5 people joined.
},
{
 'date': '3/3',
 'diff': 3 // 3 more people joined.
},
...
];

I know I can achieve this with Array.push() and a for loop:

const peopleArray = [{
    date: '3/1',
    people: 0
  },
  {
    date: '3/2',
    people: 5
  },
  {
    date: '3/3',
    people: 8
  }
];

let diffArray = [];

for (i = 0; i < peopleArray.length; i++) {
  if (i === 0) {
    // Shows 0 the first day
    diffArray.push({
      date: peopleArray[i].date,
      diff: 0
    });
  } else {
    diffArray.push({
      date: peopleArray[i].date,
      diff: peopleArray[i].people - peopleArray[i - 1].people
    });
  }
}

console.log(diffArray);

But is there a cleaner way to do this with map(), reduce() or any of those array functions?

3 Answers3

2

You could use map() and do something like:

const peopleArray = [
  {
    date: "3/1",
    people: 0,
  },
  {
    date: "3/2",
    people: 5,
  },
  {
    date: "3/3",
    people: 8,
  },
];

let diffArray = peopleArray.map((o, i, a) => ({
  date: o.date,
  diff: i > 0 ? o.people - a[i - 1].people : 0,
}));

console.log(diffArray);

The map() takes a callback function that accepts three arguments:

  1. currentValue - The current element being processed in the array;
  2. index - The index of the current element being processed in the array:
  3. array - The array map was called upon.

So you can use those parameters to achieve the same thing you've done with your for loop.

The reduce() is not really what you're looking for in this case because you want more than a single output value.

Luís Ramalho
  • 10,018
  • 4
  • 52
  • 67
1

You can use the existing object as well if you want and use the same for the graph and any other place if needed.

const peopleArray = [{
    date: '3/1',
    people: 0
  },
  {
    date: '3/2',
    people: 5
  },
  {
    date: '3/3',
    people: 8
  }
];
var peopleArrayLength = peopleArray.length;
if(peopleArrayLength > 0){
  var peopleObject = peopleArray[0];
  peopleObject.diff = 0;
  peopleArray[0] = peopleObject;
  for (i = 1; i < peopleArrayLength; i++) {
    peopleObject = peopleArray[i];
    peopleObject.diff = peopleArray[i].people - peopleArray[i-1].people;
    peopleArray[i] = peopleObject;
  }
}
console.log(peopleArray);

Outputs:

[
  {
    "date": "3/1",
    "people": 0,
    "diff": 0
  },
  {
    "date": "3/2",
    "people": 5,
    "diff": 5
  },
  {
    "date": "3/3",
    "people": 8,
    "diff": 3
  }
]
LearningEveryday
  • 584
  • 1
  • 3
  • 13
  • Inspired by @Luís Ramalho's answer, this can also be achieved with a map function: `peopleArray = peopleArray.map((cur, index, array) => ({ ...cur, diff: index > 0 ? cur.people - array[index - 1].people : 0 }));` – George Huang Apr 10 '20 at 14:15
  • For those confused by the changeable `const`, here's a discussion: [Why can I change value of a constant in javascript](https://stackoverflow.com/questions/23436437/why-can-i-change-value-of-a-constant-in-javascript). – George Huang Apr 10 '20 at 14:18
  • Thank you, I also eliminated the unnecessary if condition as well. – LearningEveryday Apr 10 '20 at 14:24
0

You can use inline If Statement as follows:

for (i = 0; i < peopleArray.length; i++) {
    var df=i!=0?(peopleArray[i].people - peopleArray[i - 1].people):0;
    diffArray.push({
      date: peopleArray[i].date,
      diff: df
    });
}
Abolfazl
  • 1,592
  • 11
  • 32
  • inline if statement are here to help, but your this one don't help you code to be more readable.. Also, the first diff is not 0 but the value of first day. `let diff = peopleArray[i].people - (i > 0 ? peopleArray[i - 1].people : 0)` – Arthur Apr 10 '20 at 05:30
  • Conditional operator surely makes code shorter, but I was looking for a way to do without for loop and `push()`. – George Huang Apr 10 '20 at 07:57