0

I want to unite all objects that have the same date value in an array of objects.

I have already tried to use the map function.

I have to following type of objects

[
{a:1, b:2, date:'2019-01-05'}, {a:12, b:22, date:'2019-01-05'}, {a:13, b:23, date:'2019-01-05'},
{a:11, b:2, date:'2019-01-06'}, {a:1, b:22, date:'2019-01-06'}, {a:1, b:23, date:'2019-01-07'}
]

now i want to have an object like this where i summarize all objects that have the same date:

[{date:'2019-01-05', data:[{a:1,b:2},....and so on]}]

so currently i came up with this solution:

  items = [...]
  moddedItems = [];
   this.items.map((data)=>{
      let tempArray = this.items.filter((obj) => {
        return obj.date === data.date;
      });
      this.moddedItems = [...this.moddedItems, {date:data.date, data:[...tempArray]}];
      console.log(this.moddedItems)
    });
Henry Sachs
  • 192
  • 18

2 Answers2

2

Array.map(...) is not the appropriate function to use here since you want a resulting array with less elements then the original one, you can generate the required result using Array.reduce(...), here is an example:

const arr = [
{a:1, b:2, date:'2019-01-05'}, {a:12, b:22, date:'2019-01-05'}, {a:13, b:23, date:'2019-01-05'},
{a:11, b:2, date:'2019-01-06'}, {a:1, b:22, date:'2019-01-06'}, {a:1, b:23, date:'2019-01-07'}
];

const result = arr.reduce((a, c) => {
  const o = {
    a: c.a,
    b: c.b
  }
  const found = a.find(({ date }) => date === c.date);
  if (found) {
    found.data.push(o)
  } else {
    a.push({
      date: c.date,
      data: [o]
    })
  }
  return a;
}, []);

console.log(result)
Titus
  • 22,031
  • 1
  • 23
  • 33
  • hey i like your answer. I have found an solution for my current data and posted it above. Would you be so kind and tell me why yours maybe be better or where the flaws are in mine? – Henry Sachs Jul 06 '19 at 15:58
  • ah it was marked as duplicate i will dig down deeper in the other thread. Thanks anyway :) – Henry Sachs Jul 06 '19 at 16:00
  • @HenrySachs Is not necessarily incorrect is just confusing, you usually use `.map` for something else, you can replace `.map` with `.forEach` since you're just iterating the array (don't use the return value from `.map`). Also, in your example, the objects in the `data` arrays with also contain the `date` property. – Titus Jul 06 '19 at 16:04
1

You could use a Map keyed by the date, and for each you would initially store an object with an empty data property, and then you would populate the data property by just iterating your original data:

const data = [
    {a:1, b:2, date:'2019-01-05'}, {a:12, b:22, date:'2019-01-05'}, {a:13, b:23, date:'2019-01-05'},
    {a:11, b:2, date:'2019-01-06'}, {a:1, b:22, date:'2019-01-06'}, {a:1, b:23, date:'2019-01-07'}
];

const map = new Map(data.map(({date}) => [date, { date, data: [] }]));
data.forEach(({date, ...o}) => map.get(date).data.push(o));
const result = [...map.values()];

console.log(result);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • hey i like your answer. I have found an solution for my current data and posted it above. Would you be so kind and tell me why yours maybe be better or where the flaws are in mine? – Henry Sachs Jul 06 '19 at 15:59
  • ah it was marked as duplicate i will dig down deeper in the other thread. Thanks anyway :) – Henry Sachs Jul 06 '19 at 16:00
  • 1
    Your own solution has a loop within a loop, which makes it less efficient. It is better to have some sort of hashing (by date), like for instance with a `Map` like I have done here. Also the other answer has the same flaw: the `find` method will potentially iterate most of the collected array, which makes it a *O(n²)* solution, while what I propose has a *O(n)* time complexity. – trincot Jul 06 '19 at 16:13
  • so i tweaked the for each to have the date also in the object the grouping is the most important for me thanks for your answer :) – Henry Sachs Jul 06 '19 at 16:31
  • 1
    Note sure what you mean, as the `date` is already in the object, but maybe you wanted the date also in the objects that are in the `data` array (that was not in your question though). Anyway, whatever works for you ;) – trincot Jul 06 '19 at 16:36