Home > other >  Push object to array and if there any duplicate date, its merge that inherit object for same date
Push object to array and if there any duplicate date, its merge that inherit object for same date

Time:08-07

This is my main array used for the table

const [tableData,setTableData] = useState([]);

this is the object pushed from my form

{ date: "2022-08-07", selectedData: { somedata: 'somedata'} }

I want to push these objects to tableData array , If there are any duplicate date need to merge selectedData object,

I expect an array like below

[
    { date: "2022-08-07", selectedData: [{ somedata: 'somedata1'},{ somedata: 'somedata2'}] },
    { date: "2022-08-08", selectedData: [{ somedata: 'somedata'}] },
]

CodePudding user response:

Here is a solution which does not require an additional pass in keying the entries by date. Since object keys do not technically have an order (even though most browsers honor it) in the ECMA spec, its probably better to keep everything as an array through the whole process.

   const pushTableData = (dataToPush) => {
      setTableDataArray(prevData => {
          const newData = [...prevData]
          const existingObjectIndex = prevData.findIndex(row => row.date === dataToPush.date)
          if (existingObjectIndex !== -1) {
              newData[existingObjectIndex] = {date: dataToPush.date, selectedData: [...prevData[existingObjectIndex].selectedData, dataToPush.selectedData]}
          } else {
              newData.push({data: dataToPush.date, selectedData: [dataToPush.selectedData])
          }

          return newData
      })
   }

CodePudding user response:

You can do this with the reduce function. First, you need to iterate on the dates and store them in an object with date keys. Then if you have added the date, you should add selectedData to it. Else, you should add the object with the date key. You can check the code here:

const dates = [
  { date: "2022-08-07", selectedData: { somedata: 'somedata'} },
  { date: "2022-08-07", selectedData: { somedata: 'somedat2'} },
  { date: "2022-08-07", selectedData: { somedata: 'somedat3'} },
  { date: "2022-08-08", selectedData: { somedata: 'somedata'} },
  { date: "2022-08-08", selectedData: { somedata: 'somedata2'} },
  { date: "2022-08-10", selectedData: { somedata: 'somedata'} },
  { date: "2022-08-11", selectedData: { somedata: 'somedata'} },
]

const result = Object.values(dates.reduce((prev, curr) => {
  return {
    ...prev,
    [curr.date]: prev[curr.date] ? { ...prev[curr.date], selectedData: [...prev[curr.date].selectedData, curr.selectedData] } : { ...curr, selectedData: [curr.selectedData] }
  }
}, {}))

console.log(result)

CodePudding user response:

You should see whether date property of selectedData exists in any of tableData. Lets say your new object from form is called newData

setTableData((tableData) => {
  const cloned = [...tableData];

  for (let i = 0; i < tableData.length; i  ) {
    if (newData.date === tableData[i].date) {
      cloned[i] = {
        ...cloned[i],
        selectedData: [...cloned[i].selectedData, newData.selectedData]
      };
      return cloned;
    }
  }

  return [...cloned, newData];
});

  1. You can implement the logic you want inside or outside of setTableData.
  2. Never mutate your state.
  • Related