You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Astro中用JS/JSX先按团队再按年份分组球员数据?

Astro实现球员数据按团队+年份分组展示方案

我使用Astro框架开发,现有接口返回的JSON数据如下,需要实现先按团队、再按年份分组展示球员,最终HTML要匹配指定格式。目前代码能正常运行但未实现分组效果,求修改前置脚本(frontmatter)和页面主体的代码。

给定的JSON响应数据

{
  "data": [
    {
      "id": 1,
      "team_name": "Team One",
      "players": [
        {
          "player_name": "Mickey Mantle",
          "players_year": {
            "year": 2024
          }
        },
        {
          "player_name": "Larry Smalls",
          "players_year": {
            "year": 2022
          }
        },
        {
          "player_name": "Ron Davis",
          "players_year": {
            "year": 2024
          }
        }
      ]
    },
    {
      "id": 2,
      "team_name": "Team Two",
      "players": [
        {
          "player_name": "Jim Abbot",
          "players_year": {
            "year": 2022
          }
        }
      ]
    }
  ]
}

期望的HTML输出

<div class="group">
  <h2>Team One</h2>
  <h3>2022</h3>
  <ul>
    <li>Larry Smalls</li>
  </ul>

  <h3>2024</h3>
  <ul>
    <li>Mickey Mantle</li>
    <li>Ron Davis</li>
  </ul>
</div>

<div class="group">
  <h2>Team Two</h2>
  <h3>2022</h3>
  <ul>
    <li>Jim Abbot</li>
  </ul>
</div>

当前的teams.astro代码

前置脚本

---
const directus = await getDirectusClient()

const response = await directus.items("teams").readByQuery({
    fields: [
        "id",
        "team_name",
        "players.player_name",
        "players.players_year.year",
    ],
})

const formattedResponse = response.data.map((team) => {
    return {
        ...team,
        yearsArr: team.players.map(player => player.players_year.year)
    }
})

const [...teams] = formattedResponse
---

页面主体

<h1>Teams Page</h1>
{
  teams.map((team) => {
    return (
      <div class='group'>
        <h2>{team.team_name}</h2>
        <ul>
          {team.players.map((player) => (
            <li>
              {player.player_name} ({player.players_year.year})
            </li>
          ))}
        </ul>
      </div>
    )
  })
}

修改方案

一、前置脚本(Frontmatter)修改

在格式化数据时,新增按年份分组的球员结构,同时生成排序后的年份数组保证展示顺序:

---
const directus = await getDirectusClient()

const response = await directus.items("teams").readByQuery({
    fields: [
        "id",
        "team_name",
        "players.player_name",
        "players.players_year.year",
    ],
})

// 格式化数据:给每个团队添加按年份分组的球员列表
const formattedResponse = response.data.map((team) => {
    // 用reduce按年份分组球员
    const playersByYear = team.players.reduce((acc, player) => {
        const year = player.players_year.year;
        // 初始化年份对应的空数组
        if (!acc[year]) {
            acc[year] = [];
        }
        acc[year].push(player);
        return acc;
    }, {});

    // 对年份进行升序排序,保证展示顺序正确
    const sortedYears = Object.keys(playersByYear).sort((a, b) => a - b);

    return {
        ...team,
        playersByYear, // 按年份分组的球员对象
        sortedYears    // 排序后的年份数组
    };
})

const [...teams] = formattedResponse
---

二、页面主体代码修改

遍历团队后,再遍历排序后的年份,渲染对应年份的球员列表:

<h1>Teams Page</h1>
{
  teams.map((team) => {
    return (
      <div class='group'>
        <h2>{team.team_name}</h2>
        {team.sortedYears.map((year) => {
          const yearPlayers = team.playersByYear[year];
          return (
            <>
              <h3>{year}</h3>
              <ul>
                {yearPlayers.map((player) => (
                  <li>{player.player_name}</li>
                ))}
              </ul>
            </>
          );
        })}
      </div>
    );
  })
}

完整teams.astro代码

---
const directus = await getDirectusClient()

const response = await directus.items("teams").readByQuery({
    fields: [
        "id",
        "team_name",
        "players.player_name",
        "players.players_year.year",
    ],
})

const formattedResponse = response.data.map((team) => {
    const playersByYear = team.players.reduce((acc, player) => {
        const year = player.players_year.year;
        if (!acc[year]) {
            acc[year] = [];
        }
        acc[year].push(player);
        return acc;
    }, {});

    const sortedYears = Object.keys(playersByYear).sort((a, b) => a - b);

    return {
        ...team,
        playersByYear,
        sortedYears
    };
})

const [...teams] = formattedResponse
---

<h1>Teams Page</h1>
{
  teams.map((team) => {
    return (
      <div class='group'>
        <h2>{team.team_name}</h2>
        {team.sortedYears.map((year) => {
          const yearPlayers = team.playersByYear[year];
          return (
            <>
              <h3>{year}</h3>
              <ul>
                {yearPlayers.map((player) => (
                  <li>{player.player_name}</li>
                ))}
              </ul>
            </>
          );
        })}
      </div>
    );
  })
}

内容的提问来源于stack exchange,提问作者scottrod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:15:46