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

使用Charts.js可视化嵌套Map对象时遇yearVal.entries()未定义错误

解决嵌套Map遍历中yearVal.entries()未定义的问题

看起来你遇到的核心问题是yearVal.entries()未定义——这说明你遍历到的yearVal并不是一个Map对象,没法调用Map专属的entries()方法。咱们一步步排查解决:

1. 先确认你的数据结构

首先得搞清楚sulyhavonta到底是嵌套Map还是普通嵌套对象:

  • 如果是嵌套Map,结构应该是这样的:
    const sulyhavonta = new Map([
      ['2023', new Map([
        ['01', { Keszeg: 100, Ponty: 150 }],
        ['02', { Keszeg: 120, Ponty: 180 }]
      ])],
      ['2024', new Map([/* ... */])]
    ]);
    
  • 如果是普通嵌套对象,结构是这样的:
    const sulyhavonta = {
      '2023': {
        '01': { Keszeg: 100, Ponty: 150 },
        '02': { Keszeg: 120, Ponty: 180 }
      },
      '2024': {/* ... */}
    };
    

2. 针对不同结构的修复方案

情况A:如果sulyhavonta是嵌套Map

如果你的数据确实是嵌套Map,但还是报错,那大概率是某个yearKey对应的yearVal不是Map(比如被意外赋值成了undefined、普通对象或者数组)。这时候可以加个类型校验,跳过无效数据:

// 把变量声明放到外层,避免每次循环重置
let labels = [];
let datasets = [];
let fishData = {};

for (let [yearKey, yearVal] of sulyhavonta.entries()) {
  // 先校验yearVal是不是Map,不是就跳过并打印警告
  if (!(yearVal instanceof Map)) {
    console.warn(`年份${yearKey}的数据格式错误,不是Map:`, yearVal);
    continue;
  }
  // 现在可以安全调用yearVal.entries()了
  for (let [monthKey, monthVal] of yearVal.entries()) {
    // 格式化年月标签,比如"2023-01"
    const formattedMonth = monthKey.toString().padStart(2, '0');
    labels.push(`${yearKey}-${formattedMonth}`);
    
    // 收集Keszeg、Ponty的数据
    const targetFish = ['Keszeg', 'Ponty'];
    targetFish.forEach(fish => {
      if (!fishData[fish]) fishData[fish] = [];
      // 当月没有数据的话默认填0
      fishData[fish].push(monthVal[fish] ?? 0);
    });
  }
}

// 转成Chart.js需要的datasets格式
datasets = Object.entries(fishData).map(([name, data]) => ({
  label: name,
  data: data,
  backgroundColor: name === 'Keszeg' ? '#FF6384' : '#36A2EB',
  borderColor: name === 'Keszeg' ? '#FF6384' : '#36A2EB',
  borderWidth: 1
}));

情况B:如果sulyhavonta是普通嵌套对象

普通对象没有entries()方法,得用Object.entries()来遍历键值对:

let labels = [];
let datasets = [];
let fishData = {};

// 用Object.entries遍历外层年份对象
for (let [yearKey, yearVal] of Object.entries(sulyhavonta)) {
  // 遍历内层月份对象
  for (let [monthKey, monthVal] of Object.entries(yearVal)) {
    const formattedMonth = monthKey.toString().padStart(2, '0');
    labels.push(`${yearKey}-${formattedMonth}`);
    
    const targetFish = ['Keszeg', 'Ponty'];
    targetFish.forEach(fish => {
      if (!fishData[fish]) fishData[fish] = [];
      fishData[fish].push(monthVal[fish] ?? 0);
    });
  }
}

// 生成datasets的逻辑和上面一致
datasets = Object.entries(fishData).map(([name, data]) => ({
  label: name,
  data: data,
  backgroundColor: name === 'Keszeg' ? '#FF6384' : '#36A2EB',
  borderColor: name === 'Keszeg' ? '#FF6384' : '#36A2EB',
  borderWidth: 1
}));

3. 额外注意点

你原来的代码里把let labels = [];放在了内层循环里,这会导致每次循环都重新声明并清空labels,最后收集不到完整的数据——一定要把这些变量的声明放到外层循环外面!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:58:43