问题描述
我在JavaScript中为将JSON对象映射到Table
中的React
而苦苦挣扎。这是有效载荷:
{
"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","probability": "1.0"
}
]
}
]
}
}
以前,markets
数组中只有一个对象,即Winner
市场。这是我针对这种情况的解决方案,其中我将直接过滤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>
)
但是,现在Finish Last
数组中刚刚添加了markets
市场。我还计划将来增加更多的市场。我希望表头看起来像这样:
<thead>
<tr className="same-col-widths">
<th>Team Name</th>
<th>Winner</th>
<th>Finish Last</th>
</thead>
在一列中显示团队名称,而在相关列中对应于正确市场的所有概率。最好的方法是什么?
解决方法
因此,首先您要使用reduce
重新格式化输入数据,以收集每个团队(表中的每一行)的所有数据,以便在创建表时可以更轻松地映射这些数据。如果将来更改输入格式,则从表创建中分离出这种逻辑还可以使您更具弹性。
const reformattedData = data["originating request"].markets.reduce(
(accumulator,market) =>
market.selections.map(({ name,probability },index) => ({
...accumulator[index],"Team name": name,[market.name]: probability,})),[],);
这为您提供了更友好的表格格式:
[
{ "Team name": "Manchester United","Winner": "1.0","Finish Last": "0.0" },{ "Team name": "Tottenham Hotspur","Winner": "0.0",{ "Team name": "Arsenal","Finish Last": "1.0" },]
然后您可以使用此新对象的键来映射并获取表标题列表,然后映射每个对象的值以创建行。
<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
中正常工作