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)
    });
0

2 Answers 2

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)

Sign up to request clarification or add additional context in comments.

3 Comments

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?
ah it was marked as duplicate i will dig down deeper in the other thread. Thanks anyway :)
@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.
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);

5 Comments

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?
ah it was marked as duplicate i will dig down deeper in the other thread. Thanks anyway :)
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.
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 :)
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 ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.