0

Group array of objects by date in javascript

There are three objects like this.

var Object1 = [
    {
        "data" : "1-1",
        "createdAt": "2022-03-01",
    },
    {
        "data" : "1-2",
        "createdAt": "2022-03-02",
    },
    {
        "data" : "1-4",
        "createdAt": "2022-03-04",
    },
    {
        "data" : "1-5",
        "createdAt": "2022-03-05",
    },
    {
        "data" : "1-6",
        "createdAt": "2022-03-06",
    },
    {
        "data" : "1-7",
        "createdAt": "2022-03-07",
    }
];

var Object2 = [
    {
        "data" : "2-1",
        "createdAt": "2022-03-02",
    },
    {
        "data" : "2-2",
        "createdAt": "2022-03-03",
    },
    {
        "data" : "2-3",
        "createdAt": "2022-03-04",
    },
    {
        "data" : "2-4",
        "createdAt": "2022-03-05",
    },
    {
        "data" : "2-5",
        "createdAt": "2022-03-06",
    },
    {
        "data" : "2-6",
        "createdAt": "2022-03-07",
    },
    {
        "data" : "2-7",
        "createdAt": "2022-03-08",
    }
];

var Object3 = [
    {
        "data" : "3-1",
        "createdAt": "2022-03-03",
    },
    {
        "data" : "3-2",
        "createdAt": "2022-03-04",
    },
    {
        "data" : "3-3",
        "createdAt": "2022-03-05",
    },
    {
        "data" : "3-4",
        "createdAt": "2022-03-06",
    },
    {
        "data" : "3-5",
        "createdAt": "2022-03-07",
    },
    {
        "data" : "3-6",
        "createdAt": "2022-03-08",
    },
    {
        "data" : "3-7",
        "createdAt": "2022-03-09",
    }
];

And I want to group them like this:

var result = [
    {
        "Object1" : "1-1",
        "Object2" : undefined or null,
        "Object3" :  undefined or null,
        "createdAt": "2022-03-01",
    },
    {
        "Object1" : "1-2",
        "Object2" : "2-1",
        "Object3" :  undefined or null,
        "createdAt": "2022-03-02",
    },
    {
        "Object1" : undefined or null,
        "Object2" : "2-2",
        "Object3" : "3-1",
        "createdAt": "2022-03-03",
    },
    {
        "Object1" : "1-4",
        "Object2" : "2-3",
        "Object3" : "3-2",
        "createdAt": "2022-03-04",
    },
    {
        "Object1" : "1-5",
        "Object2" : "2-4",
        "Object3" : "3-3",
        "createdAt": "2022-03-05",
    },
    {
        "Object1" : "1-6",
        "Object2" : "2-5",
        "Object3" : "3-4",
        "createdAt": "2022-03-06",
    },
    {
        "Object1" : "1-7",
        "Object2" : "2-6",
        "Object3" : "3-5",
        "createdAt": "2022-03-07",
    },
    {
        "Object1" : undefined or null,
        "Object2" : "2-7",
        "Object3" : "3-6",
        "createdAt": "2022-03-08",
    },
    {
        "Object1" : undefined or null,
        "Object2" : undefined or null,
        "Object3" : "3-7",
        "createdAt": "2022-03-09",
    },
]

I want to group n arrays by date.

However, the dates in each array will also be different, and it is not clear whether there is data or not. The date may be empty in the middle, or the data may be empty. If the hour, minute, and second data are mixed, they are not grouped by date.

I think I can use a foreach loop, but I don't know what I'm missing. Anyone know the answer to this?

2
  • The constraints are not very clear. Also what's the data field in the result about? Commented Apr 24, 2022 at 10:39
  • @JayCodist This "data" field was filled out by mistake while pondering the question. Unnecessary and deleted. Commented Apr 24, 2022 at 11:03

1 Answer 1

2

This is a fairly standard 'group-by' but since you have multiple arrays and you'd like to use their variable names as properties you'll need a mechanism to do this.

The example below first creates an object from the three arrays using shorthand property names, then iterates the Object.entries() of this object to group by date assigning data by the variable names as keys. To ensure that all the objects have all the array properties even when they have no relevant entries it creates a template object from the Object.keys() of your combined object and spreading it into each accumulator in the group-by operation.

const Object1 = [{ "data": "1-1", "createdAt": "2022-03-01", }, { "data": "1-2", "createdAt": "2022-03-02", }, { "data": "1-4", "createdAt": "2022-03-04", }, { "data": "1-5", "createdAt": "2022-03-05", }, { "data": "1-6", "createdAt": "2022-03-06", }, { "data": "1-7", "createdAt": "2022-03-07", }];
const Object2 = [{ "data": "2-1", "createdAt": "2022-03-02", }, { "data": "2-2", "createdAt": "2022-03-03", }, { "data": "2-3", "createdAt": "2022-03-04", }, { "data": "2-4", "createdAt": "2022-03-05", }, { "data": "2-5", "createdAt": "2022-03-06", }, { "data": "2-6", "createdAt": "2022-03-07", }, { "data": "2-7", "createdAt": "2022-03-08", }];
const Object3 = [{ "data": "3-1", "createdAt": "2022-03-03", }, { "data": "3-2", "createdAt": "2022-03-04", }, { "data": "3-3", "createdAt": "2022-03-05", }, { "data": "3-4", "createdAt": "2022-03-06", }, { "data": "3-5", "createdAt": "2022-03-07", }, { "data": "3-6", "createdAt": "2022-03-08", }, { "data": "3-7", "createdAt": "2022-03-09", }];

const objects = { Object1, Object2, Object3 };
const template = Object.fromEntries(Object.keys(objects).map(k => [k, undefined]));

const grouped = {};

for (const [objGroup, objArr] of Object.entries(objects)) {
  for (const { createdAt, data } of objArr) {
    const group = grouped[createdAt] ??= { ...template, createdAt };
    group[objGroup] = data;
  }
}

const result = Object.values(grouped);

console.log(result);

As for your vague statement, 'The date may be empty in the middle, or the data may be empty. If the hour, minute, and second data are mixed, they are not grouped by date', there's nothing to be added without actual data, but you'll need to settle on a stable property to accurately group by.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.