简体   繁体   中英

I have an array of objects and want to combine them into one object IF the one of the keys match (without overwriting the initial properties)

I have an array of objects and want to combine them into one object IF the one of the keys match(in this case the "date" key)

    Array [
  Object {
    "date": "2020-07-14",
    "finishTime": "22:00",
    "startTime": "13:30",
  },
  Object {
    "date": "2020-07-14",
    "finishTime": "12:00",
    "startTime": "08:00",
  },
]

Expected output should be

 Array [
  Object {
    "date": "2020-07-14",
    "finishTime": ["22:00", "12:00"]
    "startTime": ["13:30", "08:00"]
  },

Logic behind the solution:

  1. Create a new empty array (call it Y ) where we will store the "compact" solution.
  2. Cycle thru all elements of the original array(call it X).
  3. Check if the current element (from X ) already is in the array Y , (find the index from Y so the element can be updated).
  4. If the index is equal to -1 there is no element so we add it to Y .
  5. Otherwise (the element already exists in Y ) we retrieve the element using the index (greater that -1) -> update (with push) the finish and start time -> rewrite the updated found_element into Y using the index found before.

Here is a working example:

 // DATA const data = [ { "date": "2020-07-14", "finishTime": "22:00", "startTime": "13:30", }, { "date": "2020-07-14", "finishTime": "12:00", "startTime": "08:00", } ]; // NEW_DATA const new_data = []; data.forEach(element => { const index = new_data.findIndex(el => el.date === element.date); if(index === -1) { // Not Found new_data.push({ "date": element.date, "finishTime": [element.finishTime], "startTime": [element.startTime], }); } else { // Found let found_element = new_data[index]; found_element.finishTime.push(element.finishTime); found_element.startTime.push(element.startTime); new_data[index] = found_element; } }); console.log(`NEW DATA: ${JSON.stringify(new_data)}`);

Hope it helps:)

PS: This is a very basic solution, you must implement some sort of error checking and type checking. I suggest you to use Typescript:)

PS.PS: As you can see the original data array has not been changed:)

You can write a generic groupBy function that will combine objects by field. Example:

const data = [
    {
      "date": "2020-07-14",
      "finishTime": "22:00",
      "startTime": "13:30",
    },
    {
      "date": "2020-07-14",
      "finishTime": "12:00",
      "startTime": "08:00",
    }
];


function groupBy(array, property) {
    const temp = {};
    for (const item of array) {
        const propValue = item[property];
        if (!temp.hasOwnProperty(propValue)) {
            temp[propValue] = {
                [property]: propValue 
            };
        }

        for (const [key, value] of Object.entries(item)) {
            if (key === property) continue;

            temp[propValue][key] = (temp[propValue][key] || []).concat(value);
        }
    }
    return Object.values(temp);
}

console.dir(groupBy(data, 'date'));

Output:

[
    {
        date: "2020-07-14",
        finishTime: ["22:00", "12:00"],
        startTime: ["13:30", "08:00"],
    }
]

My example uses the ES6 syntax, if you need to, you can easily remake this code into ES5 . Also, my code is written in an imperative style, it can be rewritten using reduce and forEach if necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM