从复杂的 JSON 迭代到 Table

Iterating Into a Table from a complex JSON

我正在努力处理 JavaScript 中的可选链接,以便将 JSON 对象映射到 React 中的 Table。这是有效载荷:

{
    "originating request": {
        "id":1,
        "name":"ali",
        "markets": [
            {
                "name": "Winner",
                "selections": [
                    {
                        "name": "Manchester United",
                        "probability": "1.0"
                    },
                    {
                        "name": "Tottenham Hotspur",
                        "probability": "0.0"
                    },
                    {
                        "name": "Arsenal",
                        "probability": "0.0"
                    }
                ]
            },
            {
                "name": "Finish Last",
                "selections": [
                    {
                        "name": "Manchester United",
                        "probability": "0.0"
                    },
                    {
                        "name": "Tottenham Hotspur",
                        "probability": "0.0"
                    },
                    {
                        "name": "Arsenal",
                        "probability": "1.0"
                    }
                ]
            }
        ]
    }
}

之前,markets数组中只有一个对象,就是Winner市场。这是我针对该场景的解决方案,我将直接过滤 Winner 并遍历 table:

return (
<div>
 <Table striped bordered hover size="sm" responsive>
            <thead>
              <tr className="same-col-widths">
                <th>Team Name</th>
                <th>Winner</th>
            </thead>
            <tbody>
              {simResult?.markets?.length
                ? simResult.markets
                    .find(t => t.name === "Winner")
                    .selections.map((selection, index) => (
                      <tr key={index}>
                        <td>{selection.name}</td>
                        <td>{selection.probability}</td>
                      </tr>
                    ))
                : null}
            </tbody>
</Table>
</div>
)

但是,现在 Finish Last 市场刚刚添加到 markets 数组中。我还计划在未来增加更多的市场。我希望 table 头部看起来像这样:

            <thead>
              <tr className="same-col-widths">
                <th>Team Name</th>
                <th>Winner</th>
                <th>Finish Last</th>
            </thead>

一栏是球队名称,相关栏是正确市场对应的所有概率。执行此操作的最佳方法是什么?

所以首先您要使用 reduce 重新格式化输入数据,以收集每个团队的所有数据(table 中的每一行)以便您可以更轻松地映射创建 table 时的那些。如果将来输入格式发生变化,将此逻辑从 table-creation 中分离出来也会使您更有弹性。

const reformattedData = data["originating request"].markets.reduce(
    (accumulator, market) =>
      market.selections.map(({ name, probability }, index) => ({
        ...accumulator[index],
        "Team name": name,
        [market.name]: probability,
      })),
    [],
  );

这为您提供了更 table-friendly 的格式:

[
    { "Team name": "Manchester United", "Winner": "1.0", "Finish Last": "0.0" },
    { "Team name": "Tottenham Hotspur", "Winner": "0.0", "Finish Last": "0.0" },
    { "Team name": "Arsenal", "Winner": "0.0", "Finish Last": "1.0" },
]

然后你可以使用这个新的 object's keys 来映射并获取 table headers 的列表,然后映射通过每个 object's创建行的值。

 <table>
      <thead>
        <tr>
          {Object.keys(reformattedData[0]).map((header, index) => (
            <th key={index}>{header}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {reformattedData.map((teamData, index) => (
          <tr key={index}>
            {Object.values(teamData).map((cellInfo, index) => (
              <td key={index}>{cellInfo}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>

看到它在这个 Code Sandbox

中工作