Home > Mobile >  How to combine multiple JSON object that have same key and value
How to combine multiple JSON object that have same key and value

Time:12-16

How to combine JSON objects in the same response that has the same key and value with javascript? This is my data for example:

{
    "data": [
        {
            "name": "A",
            "description": {
                "location": "location1",
                "floor": "floor1",
            },
        },
        {
            "name": "A",
            "description": {
                "location": "location2",
                "floor": "floor1",
            },
        },
        {
            "name": "B",
            "description": {
                "location": "location3",
                "floor": "floor3",
            },
        },
    ]
}

And turn it into this:

{
    "data": [
        {
            "name": "A",
            "description": {
                "location": ["location1","location2"],
                "floor": "floor1",
            },
        },
        {
            "name": "B",
            "description": {
                "location": "location3",
                "floor": "floor3",
            },
        },
    ]
}

Basically I am someone who is new to learning javascript. Any help would be very helpful, thank you.

CodePudding user response:

You can do:

const data = {data: [{name: 'A',description: {location: 'location1',floor: 'floor1',},},{name: 'A',description: {location: 'location2',floor: 'floor1',},},{name: 'B',description: {location: 'location3',floor: 'floor3',},},],}

const result = {
  data: data.data.reduce((a, { name, description }) => {
    const index = a.findIndex((d) => d.name === name)
    if (index >= 0) {
      let location = a[index].description.location
      location = Array.isArray(location) ? location : [location]
      a[index].description.location = [...location, description.location]
    } else {
      a.push({ name, description })
    }
    return a
  }, []),
}

console.log(result)

CodePudding user response:

const list = {
    "data": [
        {
            "name": "A",
            "description": {
                "location": "location1",
                "floor": "floor1",
            },
        },
        {
            "name": "A",
            "description": {
                "location": "location2",
                "floor": "floor1",
            },
        },
        {
            "name": "B",
            "description": {
                "location": "location3",
                "floor": "floor3",
            },
        },
    ]
};


const consolidatedData = [];

for (const ele of list.data) {
    const isExist = consolidatedData.find(x => x.name === ele.name);

    if (!isExist) {
        consolidatedData.push({
            ...ele
        })
    } else {
        const objectKey = consolidatedData.findIndex(x => x.name === ele.name);
        if (objectKey > -1) {
            const description = consolidatedData[objectKey].description;
            const newDes = ele.description;

            if (newDes.location !== description.location) {
                const data = consolidatedData[objectKey].description;
                const added = [data.location, ele.description.location];
                delete consolidatedData[objectKey].description.location
                consolidatedData[objectKey].description["location"] = added
            }

            if (newDes.floor !== description.floor){
                const data = consolidatedData[objectKey].floor;
                const added = [data.floor, ele.description.floor];
                delete consolidatedData[objectKey].description.floor
                consolidatedData[objectKey].description["floor"] = added
            }

        }
    }
}

console.log(JSON.stringify(consolidatedData, null, 2));

CodePudding user response:

Here is a solution that uses an intermediate bucket object. The desired result object is then constructed from the bucket object:

const input = { "data": [ { "name": "A", "description": { "location": "location1", "floor": "floor1", }, }, { "name": "A", "description": { "location": "location2", "floor": "floor1", }, }, { "name": "B", "description": { "location": "location3", "floor": "floor3", }, }, ] };

let buckets = input.data.reduce((acc, obj) => {
  if(!acc[obj.name]) {
    acc[obj.name] = {
      locations: {},
      floors: {}
    };
  }
  acc[obj.name].locations[obj.description.location] = true; 
  acc[obj.name].floors[obj.description.floor] = true; 
  return acc;
}, {});
console.log('buckets: ', buckets);

let result = {
  data: Object.keys(buckets).map(name => {
    let locations = Object.keys(buckets[name].locations);
    let floors = Object.keys(buckets[name].floors);
    return {
      name: name,
      description: {
        location: locations.length == 1 ? locations[0] : locations,
        floor: floors.length == 1 ? floors[0] : floors
      }
    }
  })
};
console.log('result:', result);

Notes:

  • buckets object:
  • result object:
    • is using Object.keys(buckets) to get the array of names
    • .map() transforms each name into the desired object
    • your unusual array or string value for location and floor is constructed with a conditional
  • Related