Home > Blockchain >  How to merge two objects with same property in Node JS
How to merge two objects with same property in Node JS

Time:03-02

I have a JSON Data like this:

"Data": [
            {
                "time": "18:40:43",
                "count": 7,
                "endTime": "15:46:25",
                "date": "2019-01-16",
                "dow": "Thursday"
            },
            {
                "count": 11,
                "time": "16:39:52",
                "endTime": "19:41:03",
                "dow": "Thursday",
                "date": "2019-01-16"
            },
]

I want to merge two objects in this array, but it have same properties like date, dow

at the end I want to represent data like this:

"Data": [
            {
                "time": "16:39:52",
                "count": 18,
                "date": "2019-01-16",
                "dow": "Thursday"
                "endTime": "19:41:03",
            },
]

time: should be least from both objects and endTime should be largest of both of them count should be sum of both. date and dow is common in both objects

How can I merge these object in this way in node JS?

CodePudding user response:

const data=[
            {
                "time": "18:40:43",
                "count": 7,
                "endTime": "15:46:25",
                "date": "2019-01-16",
                "dow": "Thursday"
            },
            {
                "count": 11,
                "time": "16:39:52",
                "endTime": "19:41:03",
                "dow": "Thursday",
                "date": "2019-01-16"
            },
];
let date=(time)=>new Date().setHours(...time.split(":"));

let newData=[];
data.forEach((item)=>{
  let findItem=newData.findIndex((e)=>e.date===item.date && e.dow===item.dow);
  if(findItem!=-1){
  let find=data.filter((e)=>e.dow===item.dow && e.date===item.date);
  let time=find.filter((i)=>find.find(i2=>date(i2.time)>date(i.time)));
    let endTime=find.filter((i)=>find.find(i2=>date(i2.endTime)<date(i.endTime)));
  item.endTime=endTime?.[0]?.endTime || item?.endTime;
  item.time=time?.[0]?.time || item?.time;
  item.count=find.map((e)=>e.count).reduce((partialSum, a) => partialSum   a, 0);
   let findItem=newData.findIndex((e)=>e.date===item.date && e.dow===item.dow);
   if(findItem!=-1) newData.splice(findItem,1);
   newData.push(item);
  }

 else newData.push(item);
});
console.log(newData);

CodePudding user response:

Here's a simple and readable answer:

const data = [
  {
    time: "18:40:43",
    count: 7,
    endTime: "15:46:25",
    date: "2019-01-16",
    dow: "Thursday",
  },
  {
    count: 11,
    time: "16:39:52",
    endTime: "19:41:03",
    dow: "Thursday",
    date: "2019-01-16",
  },
];
const mergeObjects = (data) => {
  mergedObj = { ...data[0] };
  for (i = 1; i < data.length; i  ) {
    const obj = data[i];
    for (const key in obj) {
      switch (key) {
        case "count":
          mergedObj.count = (mergedObj.count || 0)   obj.count;
        case "time":
          mergedObj.time =
            mergedObj.time < obj.time ? mergeObjects.time : obj.time;
        case "endTime":
          mergedObj.endTime = mergedObj.endTime > obj.endTime ? mergeObjects.endTime : obj.endTime;
      }
    }
  }
  return mergedObj;
};

console.log(mergeObjects(data));

output

{
    "time": "16:39:52",
    "count": 18,
    "date": "2019-01-16",
    "dow": "Thursday"
    "endTime": "19:41:03",
},

CodePudding user response:

Assuming

  • "Data" would have only two objects inside it
  • time would be in "HH::MM::SS" format

Pass the values onto constructJSON utility function which would return the formatted value

var Data = [
            {
                "time": "18:40:43",
                "count": 7,
                "endTime": "15:46:25",
                "date": "2019-01-16",
                "dow": "Thursday"
            },
            {
                "count": 11,
                "time": "16:39:52",
                "endTime": "19:41:03",
                "dow": "Thursday",
                "date": "2019-01-16"
            },
]


function constructJSON(data)
{
 const returnData = {}
 returnData['count'] = data[0].count   data[1].count
 returnData['date'] = data[0].date    // since its common for both
 returnData['dow'] = data[0].dow      // since its common for both
 returnData['time'] = parseInt(data[0].time.split(':').join(''),10) < parseInt(data[1].time.split(':').join(''),10) ? data[0].time:data[1].time;
  returnData['endTime'] = parseInt(data[0].endTime.split(':').join(''),10) > parseInt(data[1].endTime.split(':').join(''),10) ? data[0].endTime:data[1].endTime;
 
  return returnData
}

console.log(constructJSON(Data))

CodePudding user response:

If you use Array.reduce, you should be able to do this pretty easily, it should also expand to let you expand with more than just 2 objects in the array.

const data = [{
    "time": "18:40:43",
    "count": 7,
    "endTime": "15:46:25",
    "date": "2019-01-16",
    "dow": "Thursday"
  },
  {
    "count": 11,
    "time": "16:39:52",
    "endTime": "19:41:03",
    "dow": "Thursday",
    "date": "2019-01-16"
  },
];

//res will contain the output
const res = data.reduce(function(acc, curr) {
    
  //Initially the accumulator will be null
  if (!acc) return curr;
  
  //Add the counts up
  acc.count  = curr.count;

  //Convert both times into dates and find the minimum
  const accTime = new Date(acc.date   'T'   acc.time); //We add the T here since that's just how the Date constructor accepts times
  const currTime = new Date(acc.date   'T'   curr.time);
  acc.time = new Date(Math.min(accTime, currTime)).toTimeString().split(' ')[0]; //See https://stackoverflow.com/questions/19346405/how-to-get-hhmmss-from-date-object

  //Do the same for the end times but find the maximum
  const accEndTime = new Date(acc.date   'T'   acc.endTime);
  const currEndTime = new Date(acc.date   'T'   curr.endTime);
  acc.endTime = new Date(Math.max(accEndTime, currEndTime)).toTimeString().split(' ')[0];
  return acc;
});
console.log(res);

CodePudding user response:

Another way of merging - all keys are combined, the common keys are overwritten by the second object, but count, time and endTime are calculated by special conditions

const 
   data = [{"time": "18:40:43","count": 7,"endTime": "15:46:25","date": "2019-01-16","dow": "Thursday"},{"count": 11,"time": "16:39:52","endTime": "19:41:03","dow": "Thursday","date": "2019-01-16"}],

  [first, last] = data,
  dumbDate = '2000-01-01 ',

  result = {
    ...first,
    ...last,
    count: first.count   last.count,
    time: (new Date(`${dumbDate}${first.time}`) < new Date(`${dumbDate}${last.time}`)) ? first.time : last.time,
    endTime: (new Date(`${dumbDate}${first.endTime}`) > new Date(`${dumbDate}${last.endTime}`)) ? first.endTime : last.endTime,
};

console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}

  • Related