简体   繁体   English

从复杂 JSON 迭代到表中

[英]Iterating Into a Table from a complex JSON

I am struggling with optional chaining in JavaScript to map a JSON object to a Table in React .我正在努力解决 JavaScript 到Table和 JSON React中的可选链接。 This is the payload:这是有效载荷:

{
    "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"
                    }
                ]
            }
        ]
    }
}

Previously, there was only one object in the markets array, which is the Winner market.之前markets阵列中只有一个object,即Winner市场。 This was my solution for that scenario, where I would filter for the Winner straightaway and iterate through the table:这是我针对该场景的解决方案,我将直接筛选Winner并遍历表格:

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>
)

However, now there the Finish Last market has just been added in the markets array.然而,现在Finish Last市场刚刚被添加到markets阵列中。 I also plan to add more markets in the future.我还计划在未来增加更多的市场。 I would like the table head to look something like this:我希望表头看起来像这样:

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

With the team names in one column, and all the probabilities corresponding to the correct market in the relevant columns.在一列中包含团队名称,以及在相关列中对应于正确市场的所有概率。 What is the best way to go about doing this? go 关于这样做的最佳方法是什么?

So first of all you want to reformat the input data using a reduce , to collect all the data for each team (each row in the table) so you can more easily map through those when creating the table.因此,首先您要使用reduce重新格式化输入数据,以收集每个团队的所有数据(表中的每一行),以便在创建表时更轻松地通过 map。 Splitting out this logic from the table-creation also makes you more resilient if that input format changes in the future.如果将来输入格式发生变化,从表创建中分离出这个逻辑也会让你更有弹性。

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

This gives you it in the more table-friendly format of:这为您提供了更适合表格的格式:

[
    { "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" },
]

And then you can use this new object's keys to map and get the list of table headers, and then map through each object's values to create the rows.然后您可以使用这个新对象的键 map 并获取表头列表,然后 map 通过每个对象的值创建行。

 <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>

See it working in this Code Sandbox看到它在这个代码沙箱中工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM