我正在尝试根据另一个属性的先前值更新每个当前值。
实际上,我需要用日期来完成任务,但为了简单起见,我将用简单的数字来解释我的问题。
我有
开始
,即1
Stop
,已定义结束
持续时间
,已定义
我的目标
开始
= 上一个索引的持续时间
+ 上一个索引的结束
End
=Start
+ 当前值的Stop
为了说明这一点,我添加了表格的屏幕截图,它应该是什么样子:
当前 View :
下面的代码和 sandbox link
import React from "react";
import { AgGridReact } from "ag-grid-react";
import "./styles.css";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css";
function App() {
let start = 1;
const [gridApi, setGridApi] = React.useState(null);
const [gridColumnApi, setGridColumnApi] = React.useState(null);
const onGridReady = (params) => {
setGridApi(params.api);
setGridColumnApi(params.columnApi);
};
const defaultColDef = {
flex: 1,
editable: true
};
const columnDefs = [
{
headerName: "Name",
field: "name"
},
{
headerName: "start",
field: "updatedStart"
},
{ headerName: "stop", field: "stop" },
{
headerName: "end",
field: "end"
},
{
headerName: "duration",
field: "duration",
colId: "duration"
}
];
const rowData = React.useMemo(
() => [
{
name: "John",
stop: 10,
duration: 5
},
{
name: "David",
stop: 15,
duration: 8
},
{
name: "Dan",
stop: 20,
duration: 6
}
],
[]
);
const rowDataWithStart = React.useMemo(() => {
return (
rowData &&
rowData.map((row, i) => ({
...row,
start: start
}))
);
}, [start, rowData]);
const rowDataWitEnd = React.useMemo(() => {
return (
rowDataWithStart &&
rowDataWithStart.map((row, i) => ({
...row,
end: row.start + row.stop
}))
);
}, [rowDataWithStart]);
//this function(rowDataWitUpdatedStart) should get the previous value of end and duration and get the total
const rowDataWitUpdatedStart = React.useMemo(() => {
return (
rowDataWitEnd &&
rowDataWitEnd.map((row, i) => ({
...row,
updatedStart: row.end + row.duration
}))
);
}, [rowDataWitEnd]);
return (
<div className="App">
<h1 align="center">React-App</h1>
<div className="ag-theme-alpine">
<AgGridReact
columnDefs={columnDefs}
rowData={rowDataWitUpdatedStart}
defaultColDef={defaultColDef}
domLayout={"autoHeight"}
onGridReady={onGridReady}
></AgGridReact>
</div>
</div>
);
}
export default App;
我尝试使用我使用的库中的valueGetter
来完成任务:AG Grid
,但似乎不是最好的方法。看我的previous question
任何帮助将不胜感激
最佳答案
您可以使用 Array.prototype.reduce 一次性完成您想要的所有操作,而不是逐步转换数据。我们在这里使用 Array.prototype.reduce 的方式几乎与使用 Array.prototype.map 的方式类似(我们将对象推送为 -到一个新数组中,因此没有数据转换),但优点是我们可以访问第三个参数中的当前索引,这允许我们访问累加器中前一项的值。
Array.prototype.map
在这种情况下不起作用,因为在每次迭代中它都无法访问前一项中更新的 start
,除非您有一种将其存储在函数外部的黑客方式。
根据您的逻辑,您希望 start
是前一项的持续时间 + 结束,我们可以使用以下逻辑:
curCopy.start = idx === 0 ? 1 : (acc[idx - 1].duration + acc[idx - 1].end);
...基本上是说:
- 如果我们在第一项,则只需从
1
的种子值开始start
- 如果不是,那么我们访问累加器的前一个条目(当前索引减一),并访问其
duration
和end
属性。将它们总结起来并用于开始
在返回的新对象内存数组中使用此逻辑:
const updatedRowData = React.useMemo(() => {
const updated = rowData.reduce((acc, cur, idx) => {
const curCopy = {...cur};
const previous = acc[idx - 1];
curCopy.start = idx === 0 ? 1 : (previous.duration + previous.end);
curCopy.end = curCopy.start + curCopy.stop;
acc.push(curCopy);
return acc;
}, []);
return updated;
}, [rowData]);
然后在模板中,只需使用 rowData={updatedRowData}
。
它应该生成您期望的结果:
我已经 fork 了您的沙箱来创建一个概念验证示例:
关于javascript - 如何根据对象数组中的先前值更新值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71017055/