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

JSON数组多级筛选异常:Semester下拉框返回空数组求助

问题:D3学生成绩图表生成器的学期筛选返回空数组

我正在用D3构建学生成绩与科目关联的图表生成器,现有如下JSON数据:

var jsonData = [
  {
    "_id": "64fef13b9122b9e16aafddab",
    "xie_id": 202201018,
    "name": "Jane",
    "branch": "COMPS",
    "year": 2020,
    "sem": 3,
    "exam_type": "IAT-1",
    "Subject": "DSA",
    "Marks": 72,
    "__v": 0
  },
  {
    "_id": "64fef13b9122b9e16aafddae",
    "xie_id": 202201019,
    "name": "John",
    "branch": "IT",
    "year": 2021,
    "sem": 1,
    "exam_type": "IAT-1",
    "Subject": "Maths_3",
    "Marks": 45,
    "__v": 0
  },
  {
    "_id": "64fef13b9122b9e16aafddc9",
    "xie_id": 202201028,
    "name": "Isabella",
    "branch": "IT",
    "year": 2021,
    "sem": 1,
    "exam_type": "IAT-1",
    "Subject": "CG",
    "Marks": 12,
    "__v": 0
  }
];

功能逻辑:传入数组后解析分支展示在下拉框;选择分支后筛选对应年份展示;选择年份后筛选对应分支+年份的学期,但此步骤返回空数组。分支和年份筛选正常,求排查逻辑问题。


相关代码

分支下拉框

<div>
  <div>
    <label htmlFor="branch">Branch:</label>
    <select id="branch" value={selectedBranch} onChange={(e) => setSelectedBranch(e.target.value)}>
      <option value="">All Branches</option>
      {branches.map((branch) => (
        <option key={branch} value={branch}>
          {branch}
        </option>
      ))}
    </select>
  </div>
</div>

年份下拉框

<div>
  <label htmlFor="year">Year:</label>
  <select id="year" value={selectedYear} onChange={(e) => setSelectedYear(e.target.value)}>
    <option value="">All Years</option>
    {years.map((year) => (
      <option key={year} value={year}>
        {year}
      </option>
    ))}
  </select>
</div>

学期下拉框

<div>
  <label htmlFor="semester">Semester:</label>
  <select id="semester" value={selectedSemester} onChange={(e) => setSelectedSemester(e.target.value)}>
    <option value="">All Semesters</option>
    {semesters.length > 0 ? (
      semesters.map((semester) => (
        <option key={semester} value={semester}>
          {semester}
        </option>
      ))
    ) : (
      <option disabled>No semesters found</option>
    )}
  </select>
</div>

分支筛选逻辑

useEffect(() => {
  const uniqueBranches = [...new Set(jsonData.map((d) => d.branch))];
  setBranches(uniqueBranches);
}, [jsonData]);

年份筛选逻辑

useEffect(() => {
  if (selectedBranch) {
    const uniqueYears = [...new Set(jsonData.filter((d) => d.branch === selectedBranch).map((d) => d.year))];
    setYears(uniqueYears);
    setSelectedYear('');
    setSelectedSemester('');
    setSelectedName('');
    setSelectedExamType('');
  } else {
    setYears([]);
    setSemesters([]);
    setNames([]);
    setExamTypes([]);
  }
}, [selectedBranch, jsonData]);

学期筛选逻辑

useEffect(() => {
  if (selectedYear) {
    const uniqueSemesters = [...new Set(jsonData.filter((d) => d.branch === selectedBranch && d.year === selectedYear).map((d) => d.sem))];
    setSemesters(uniqueSemesters);
    setSelectedSemester('');
    setSelectedName('');
    setSelectedExamType('');
  } else {
    setSemesters([]);
    setNames([]);
    setExamTypes([]);
  }
}, [selectedYear, selectedBranch, jsonData]);

问题原因与解决方案

核心问题:类型不匹配

从下拉框获取的selectedYear是字符串类型(select控件的value默认都是字符串),但JSON数据里的year是数字类型。直接用===全等比较时,类型不同导致匹配失败,最终筛选出空数组。

两种修改方案

方案1:在学期筛选时将selectedYear转为数字

修改学期筛选的useEffect中的过滤条件:

const uniqueSemesters = [...new Set(jsonData.filter((d) => d.branch === selectedBranch && d.year === Number(selectedYear)).map((d) => d.sem))];
方案2:在年份筛选时将数字转为字符串(推荐,保持前后类型一致)

修改年份筛选的useEffect,把获取的year转为字符串后再存入years:

const uniqueYears = [...new Set(jsonData.filter((d) => d.branch === selectedBranch).map((d) => String(d.year)))];

这样下拉框的value和JSON数据中转后的year都是字符串类型,后续比较不会出现类型不匹配的问题。

验证

以选择IT分支、2021年份为例,修改后筛选逻辑会匹配到两条数据,提取出sem:1,学期下拉框就能正常显示选项。


内容的提问来源于stack exchange,提问作者4bit guy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:05:53