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
相关产品推荐
相关产品推荐

