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];
});
- You can implement the logic you want inside or outside of
setTableData
. - Never mutate your state.