javascript - 如何根据对象数组中的先前值更新值?

标签 javascript reactjs ag-grid

我正在尝试根据另一个属性的先前值更新每个当前值。

实际上,我需要用日期来完成任务,但为了简单起见,我将用简单的数字来解释我的问题。

我有

  1. 开始,即1
  2. Stop,已定义
  3. 结束
  4. 持续时间,已定义

我的目标

  • 开始 = 上一个索引的持续时间 + 上一个索引的结束
  • End = Start + 当前值的Stop

为了说明这一点,我添加了表格的屏幕截图,它应该是什么样子:

enter image description here

当前 View :

enter image description here

下面的代码和 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. 如果我们在第一项,则只需从 1 的种子值开始 start
  2. 如果不是,那么我们访问累加器的前一个条目(当前索引减一),并访问其 durationend 属性。将它们总结起来并用于开始

在返回的新对象内存数组中使用此逻辑:

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}。 它应该生成您期望的结果:

Expected table results

我已经 fork 了您的沙箱来创建一个概念验证示例:

Edit ag-grid (forked)

关于javascript - 如何根据对象数组中的先前值更新值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71017055/

相关文章:

ag-grid - autoGroupColumnDef 上的 aggrid 单元格渲染器使树变平

javascript - 在 JavaScript 中为文本分配不同颜色的按钮

javascript - window.onload 和 document.ready : execution order in case specified multiple times

javascript - Processing.js 和 JavaScript 语法

javascript - 如何避免与 React hooks 相关的范围问题

javascript - 如何读取ag-grid中每个单元格的样式(或获取html元素)

javascript - 如何删除农业网格中的重复项( Angular )

javascript - Xcode 中的 UI 自动化

javascript - 如何在 React 上获取动态引用

reactjs - 为什么我不断收到 500(内部服务器错误)GET http ://localhost:3000/favicon. ico 500(内部服务器错误)?