How to classify an array of object based on a property?

Hi all, I have an array of object and would like to classify it based on a property (date in this case). How should I achieve it?

This the array of object :

[
  { julia: 1, date: '02/06/2020' },
  { julio: 3, date: '02/06/2020' },
  { julian: 5, date: '02/06/2020' },
  { julia: 3, date: '21/07/2021' },
  { julio: 1, date: '21/07/2021' },
  { julian: 2, date: '21/07/2021' },
  { julia: 7, date: '27/12/2022' },
  { julio: 3, date: '27/12/2022' },
  { julian: 1, date: '27/12/2022' }
]

Here is the expected output :

[
  {
    date: "02/06/2020",
    julia: 1,
    julio: 3,
    julian: 5,
    total: 9
  },
  {
    date: "21/07/2021",
    julia: 3,
    julio: 1,
    julian: 2,
    total: 6
  },
  {
    date: "27/12/2022",
    julia: 7,
    julio: 3,
    julian: 1,
    total: 11
  },
]

This is a picture of before (current) and after (expected output) :

Any suggestion is appreciated, thanks!

my first thought is that you would need some kind of hashmap structure.
Something that you can map into by date and that can hold a list of objects.
What were your thoughts?

Thanks for replying, currently I am trying to filter date like this :

let toExpected = [
  { julia: 1, date: '02/06/2020' },
  { julio: 3, date: '02/06/2020' },
  { julian: 5, date: '02/06/2020' },
  { julia: 3, date: '21/07/2021' },
  { julio: 1, date: '21/07/2021' },
  { julian: 2, date: '21/07/2021' },
  { julia: 7, date: '27/12/2022' },
  { julio: 3, date: '27/12/2022' },
  { julian: 1, date: '27/12/2022' }
];

const dates = toExpected.map(x => x.date);
let filtered = toExpected.filter(({date}, index) => !dates.includes(date, index + 1));
console.log("filtered :", filtered);
// filtered : [
//   { julian: 5, date: '02/06/2020' },
//   { julian: 2, date: '21/07/2021' },
//   { julian: 1, date: '27/12/2022' }
// ]

However, I have not succeed in merging elements of the toExpected array whose dates are same.

I think what @hbar1st was implying is that you want to make an intermediate object (sometimes called a hashmap) that you can then convert into the array you want.

1st step - the input

[
  { julia: 1, date: '02/06/2020' },
  { julio: 3, date: '02/06/2020' },
  { julian: 5, date: '02/06/2020' },
  { julia: 3, date: '21/07/2021' },
  { julio: 1, date: '21/07/2021' },
  { julian: 2, date: '21/07/2021' },
  { julia: 7, date: '27/12/2022' },
  { julio: 3, date: '27/12/2022' },
  { julian: 1, date: '27/12/2022' }
]

2nd step - the intermediate structure. You can loop through the input array to create this object.

{
  "02/06/2020": {
    julia: 1,
    julio: 3,
    julian: 5,
  },
  "21/07/2021": {
    julia: 3,
    julio: 1,
    julian: 2,
  },
  "27/12/2022": {
    julia: 7,
    julio: 3,
    julian: 1,
  }
}

3rd step - the output. You can loop through each key/value pair of the above object to create this array.

[
  {
    date: "02/06/2020",
    julia: 1,
    julio: 3,
    julian: 5,
    total: 9
  },
  {
    date: "21/07/2021",
    julia: 3,
    julio: 1,
    julian: 2,
    total: 6
  },
  {
    date: "27/12/2022",
    julia: 7,
    julio: 3,
    julian: 1,
    total: 11
  },
]
1 Like

My first instinct would be a reduce method. Something with the schema of

const reduceMyData = (acc, date) => {
  // do the magic
}

const newData = oldData.reduce(reduceMyData , [])

I’ll leave the magic for you, but basically, you will be checking if that date already exists in the accumulator. If it doesn’t, you return a new accumulator where you’ve add it with an object with the name and value. If it does exist, then you return a new accumulator where you’ve added a new name/value to the copy of the object for that date.

I mean, that is a very readable, functional JS approach. I like it because it is very readable. If you have massive amounts of data, it may not be the most efficient. But it for most cases, it’s probably fine - and if you need speed, maybe JS isn’t the best language anyway.

I have a solution, but I’ll let you work on yours first.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.