如何使用 javascript 获取嵌套对象中所有子项的单个 属性?
How to get a single property of all children in a nested object using javascript?
对于显示国家/地区随时间变化的数据(使用 d3)的交互式地图,我有一个名为 dataset
的大型对象。 dataset
的属性也是由国家名称标识的对象。下一层是对象,同样由年份表示。最后一层终于是要显示的数据了。
结构是这样的:
dataset
- CountryA
- 2010
- population: 4000000
- crime rate: 17.4
- GDP per capita: 2800
- 2011
- population: 4100000
- crime rate: 16.8
- GDP per capita: 2900
- ...
- CountryB
- 2010
- population: 3700000
- crime rate: 25.6
- GDP per capita: 1200
- 2011
- population: 3850000
- crime rate: 27.2
- GDP per capita: 1180
- ...
- ...
现在,为了更新地图,我需要找到特定 属性 的范围,以便调整我想要使用的颜色范围。例如,如果我想获得 2010 年犯罪率的最小值和最大值,是否有简单的命令来检索该信息?
我确实有一个所有可用国家的列表,当然可以遍历该列表并获取指定年份的值,将其与全球 min/max 值进行比较,并在必要时进行更改(使用 Math.min/max
).我只是想知道,如果我有一个简单的方法,比如
var crimeRateLow = getGlobalMin(dataset, 2, "crime rate");
// magic function
function getGlobalMin(object, unspecifiedLevels, indicator) { ... }
我目前正在使用以下函数,j
是指标,year
是全局设置变量:
function getRange(j) {
var jRange = {"min": 0, "max": 0};
for (k in dataset) {
jRange["min"] = Math.min(jRange["min"], dataset[k][year][j]);
jRange["max"] = Math.max(jRange["max"], dataset[k][year][j]);
}
return jRange;
}
虽然 d3 中没有内置函数解决您的问题,但 d3 可能有助于优雅地解决它。
通过将 d3.values()
to get an array of property values (still objects) of the associative array. These property values/objects are afterwards mapped
重复应用于仅包含感兴趣的字段值的数组,将嵌套对象取消嵌套到包含感兴趣的字段值的较小数组中。
使用d3.merge()
将这些数组合并为一个大数组。
应用d3.extent()
从中获取全局范围(即数组[min,max
])。
function getGlobalExtent(data, field) {
return d3.extent( // (3.) Get the global extent.
d3.merge( // (2.) Merge all arrays into a single one.
d3.values(data) // (1.) Array of all country objects in dataset
.map(function(country) { // (1.) Map each country to array of field values for all years within.
return d3.values(country) // (1.) Array of years in each country
.map(function(year) { // (1.) Map each year to the requested field value.
return year[field];
});
})
)
);
}
我整理了一个工作片段:
var dataset = {
"CountryA": {
"2010": {
"population": 4000000,
"crime rate": 17.4,
"GDP per capita": 2800
},
"2011": {
"population": 4100000,
"crime rate": 16.8,
"GDP per capita": 2900
}
},
"CountryB": {
"2010": {
"population": 3700000,
"crime rate": 25.6,
"GDP per capita": 1200
},
"2011": {
"population": 3850000,
"crime rate": 27.2,
"GDP per capita": 1180
}
}
};
function getGlobalExtent(data, field) {
return d3.extent( // (3.) Get the global extent.
d3.merge( // (2.) Merge all arrays into a single one.
d3.values(data) // (1.) Array of all country objects in dataset
.map(function(country) { // (1.) Map each country to array of field values for all years within.
return d3.values(country) // (1.) Array of years in each country
.map(function(year) { // (1.) Map each year to the requested field value.
return year[field];
});
})
)
);
}
// population: 3700000,4100000
//console.log("population:", getGlobalExtent(dataset, "population").join());
// crime rate: 16.8,27.2
//console.log("crime rate:", getGlobalExtent(dataset, "crime rate").join());
// GDP per capita: 1180,2900
//console.log("GDP per capita:", getGlobalExtent(dataset, "GDP per capita").join());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
对于显示国家/地区随时间变化的数据(使用 d3)的交互式地图,我有一个名为 dataset
的大型对象。 dataset
的属性也是由国家名称标识的对象。下一层是对象,同样由年份表示。最后一层终于是要显示的数据了。
结构是这样的:
dataset
- CountryA
- 2010
- population: 4000000
- crime rate: 17.4
- GDP per capita: 2800
- 2011
- population: 4100000
- crime rate: 16.8
- GDP per capita: 2900
- ...
- CountryB
- 2010
- population: 3700000
- crime rate: 25.6
- GDP per capita: 1200
- 2011
- population: 3850000
- crime rate: 27.2
- GDP per capita: 1180
- ...
- ...
现在,为了更新地图,我需要找到特定 属性 的范围,以便调整我想要使用的颜色范围。例如,如果我想获得 2010 年犯罪率的最小值和最大值,是否有简单的命令来检索该信息?
我确实有一个所有可用国家的列表,当然可以遍历该列表并获取指定年份的值,将其与全球 min/max 值进行比较,并在必要时进行更改(使用 Math.min/max
).我只是想知道,如果我有一个简单的方法,比如
var crimeRateLow = getGlobalMin(dataset, 2, "crime rate");
// magic function
function getGlobalMin(object, unspecifiedLevels, indicator) { ... }
我目前正在使用以下函数,j
是指标,year
是全局设置变量:
function getRange(j) {
var jRange = {"min": 0, "max": 0};
for (k in dataset) {
jRange["min"] = Math.min(jRange["min"], dataset[k][year][j]);
jRange["max"] = Math.max(jRange["max"], dataset[k][year][j]);
}
return jRange;
}
虽然 d3 中没有内置函数解决您的问题,但 d3 可能有助于优雅地解决它。
通过将
d3.values()
to get an array of property values (still objects) of the associative array. These property values/objects are afterwardsmapped
重复应用于仅包含感兴趣的字段值的数组,将嵌套对象取消嵌套到包含感兴趣的字段值的较小数组中。使用
d3.merge()
将这些数组合并为一个大数组。应用
d3.extent()
从中获取全局范围(即数组[min,max
])。function getGlobalExtent(data, field) { return d3.extent( // (3.) Get the global extent. d3.merge( // (2.) Merge all arrays into a single one. d3.values(data) // (1.) Array of all country objects in dataset .map(function(country) { // (1.) Map each country to array of field values for all years within. return d3.values(country) // (1.) Array of years in each country .map(function(year) { // (1.) Map each year to the requested field value. return year[field]; }); }) ) ); }
我整理了一个工作片段:
var dataset = {
"CountryA": {
"2010": {
"population": 4000000,
"crime rate": 17.4,
"GDP per capita": 2800
},
"2011": {
"population": 4100000,
"crime rate": 16.8,
"GDP per capita": 2900
}
},
"CountryB": {
"2010": {
"population": 3700000,
"crime rate": 25.6,
"GDP per capita": 1200
},
"2011": {
"population": 3850000,
"crime rate": 27.2,
"GDP per capita": 1180
}
}
};
function getGlobalExtent(data, field) {
return d3.extent( // (3.) Get the global extent.
d3.merge( // (2.) Merge all arrays into a single one.
d3.values(data) // (1.) Array of all country objects in dataset
.map(function(country) { // (1.) Map each country to array of field values for all years within.
return d3.values(country) // (1.) Array of years in each country
.map(function(year) { // (1.) Map each year to the requested field value.
return year[field];
});
})
)
);
}
// population: 3700000,4100000
//console.log("population:", getGlobalExtent(dataset, "population").join());
// crime rate: 16.8,27.2
//console.log("crime rate:", getGlobalExtent(dataset, "crime rate").join());
// GDP per capita: 1180,2900
//console.log("GDP per capita:", getGlobalExtent(dataset, "GDP per capita").join());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>