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

D3 v4中nest()函数生成带$符号的键,如何正确访问?

关于D3 v4中d3.nest()生成带$前缀键的访问问题

问题背景

我首次使用D3的d3.nest()函数绘制分级统计图,按国家和年份嵌套数据时,发现国家(如$AUS)和年份(如$1960)的键均被添加了$符号。已知这是D3 v4的预期行为,但想确认是否需通过dataByCountryByYear['$AUS']访问,同时想了解该场景下正确的对象键访问方式。

相关代码片段:

function ready(error, country_data, lfpr_data) { 
  // converting strings to numbers where necessary 
  lfpr_data.forEach(d => { 
    d.year = +d.year 
    d.female_lfpr = +d.female_lfpr; 
    d.male_lfpr = +d.male_lfpr; 
  }); 
  // nesting by country and year i.e for each country all years beneath it 
  var dataByCountryByYear = d3.nest() 
    .key(function(d) { return d.country; }) 
    .key(function(d) { return d.year; }) 
    .map(lfpr_data); 
  console.log(dataByCountryByYear['$AUS']) 
  country_data.features.forEach(each_country => { 
    each_country.properties.years = dataByCountryByYear[each_country.id] 
  }); 
}

数据样例:

year country country_name region female_lfpr male_lfpr total_lfpr
1960 ABW Aruba Latin America & Caribbean NA NA NA
1960 AFG Afghanistan South Asia NA NA NA
1960 AGO Angola Sub-Saharan Africa NA NA NA
...


解答

首先明确:你看到的$前缀确实是D3 v4的预期行为——因为d3.nest().map()返回的不是普通JavaScript对象,而是D3专属的Map对象。它用$前缀来处理两种情况:一是非字符串类型的键(比如你转成数字的year),二是避免键名和Map对象自身的方法(比如get、set)冲突。

1. 正确的访问方式

你用dataByCountryByYear['$AUS']确实能拿到数据,但这只是D3 Map对普通对象属性访问的模拟,更规范、更可靠的方式是使用D3 Map内置的.get()方法:

// 获取AUS国家的所有年份数据
const ausData = dataByCountryByYear.get('AUS');
// 获取AUS国家1960年的数据(注意这里用数字1960,和你转换后的year类型匹配)
const aus1960Data = ausData.get(1960);

这种方式不需要加$前缀,D3会自动处理键的类型匹配,也不用担心键名和方法名冲突的问题。

2. 修正你的代码

你当前代码中dataByCountryByYear[each_country.id]的写法存在隐患,建议改成.get()方法:

country_data.features.forEach(each_country => {
  // 用get()替代属性访问
  each_country.properties.years = dataByCountryByYear.get(each_country.id);
});

3. 可选:转成普通JavaScript对象

如果你更习惯用普通对象操作,可以把d3.nest()的输出换成普通对象,只需要把.map()改成.object():

var dataByCountryByYear = d3.nest()
  .key(function(d) { return d.country; })
  .key(function(d) { return d.year; })
  .object(lfpr_data);

这样生成的就是普通JS对象,键不会带$前缀,你可以直接用dataByCountryByYear['AUS']['1960']访问(注意这里年份是字符串,因为.object()会把所有键转成字符串类型)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:14:50