[英]D3 v4 how to synchronously iterate through data
I have an array called states
that is an array of arrays.我有一个名为states
的数组,它是一个数组数组。 Each array element has 2 items, a United States state name and its abbreviation:每个数组元素有 2 个项目,一个美国州名及其缩写:
states = [
['Arizona', 'AZ'],
['Alabama', 'AL'],
['Alaska', 'AK'],
['Arkansas', 'AR'],
['California', 'CA'],
...
]
I have a map called statesData
with key = state abbreviation.我有一个名为statesData
的地图,键 = state 缩写。 I'm trying to use the states
array to create a new map with the same values as statesData
, but with the key equal to the state's full name:我正在尝试使用states
数组创建一个与statesData
具有相同值的新地图,但键等于州的全名:
function setStatesFullData(statesFullData, statesData) {
statesData.each(function(key, value) {
states.forEach(function(element) {
if (key == element[1]) {
statesFullData.set(element[0], value);
}
})
})
console.log(statesFullData.size());
return statesFullData;
}
var statesFullData = d3.map();
statesFullData = setStatesFullData(statesFullData, statesData);
Output:输出:
0
This is expected due to variable scoping and (I believe) that map.each
and array.forEach
are asynchronous functions.由于变量范围和(我相信) map.each
和array.forEach
是异步函数,这是预期的。
I currently don't understand how I can around this: the data has to exist outside the statesData.forEach
function to be used, and by then the data will not exist.我目前不明白如何解决这个问题:数据必须存在于statesData.forEach
函数之外才能使用,届时数据将不存在。
I think there's something about asynchronous development that I'm missing.我认为我缺少一些关于异步开发的东西。
I can provide more info on request.我可以应要求提供更多信息。 Thank you!谢谢!
Full Demo (also below): https://codepen.io/Alexander9111/pen/YzXNGyZ )完整演示(也在下面): https : //codepen.io/Alexander9111/pen/YzXNGyZ )
A step-by-step explanation is at the bottom of this answer分步说明位于此答案的底部
const states = [ ['Arizona', 'AZ'], ['Alabama', 'AL'], ['Alaska', 'AK'], ['Arkansas', 'AR'], ['California', 'CA'] ]; const statesReversed = states.map((child, index) =>{ return [...child.reverse()] }); console.log(statesReversed); const statesConversionObject = Object.fromEntries(statesReversed); console.log(statesConversionObject); const statesData = { 'AZ': ['Some', 'Data'], 'AL': ['Some', 'Data'], 'AK': ['Some', 'Data'], 'AR': ['Some', 'Data'], 'CA': ['Some', 'Data'] }; const statesDataModified = {}; for (let key in statesData){ const newKey = statesConversionObject[key]; statesDataModified[newKey] = statesData[key]; } console.log(statesDataModified); const statesFullData = d3.map(statesDataModified); console.log(statesFullData);
Step by Step:一步步:
Original Data:原始数据:
const states = [
['Arizona', 'AZ'],
['Alabama', 'AL'],
['Alaska', 'AK'],
['Arkansas', 'AR'],
['California', 'CA']
];
const statesData = {
'AZ': ['Some', 'Data'],
'AL': ['Some', 'Data'],
'AK': ['Some', 'Data'],
'AR': ['Some', 'Data'],
'CA': ['Some', 'Data']
};
Reverse our array of arrays (might be called array of touples in other languages).反转我们的数组数组(在其他语言中可能称为元组数组)。 We do the reversing by using array.map()
to iterate over the outer array and [...child.reverse()]
to reverse the inner array:我们通过使用array.map()
迭代外部数组和[...child.reverse()]
来反转内部数组来进行反转:
const statesReversed = [ ['AZ', 'Arizona',], ['AL', 'Alabama'], ['AK', 'Alaska'], ['AR', 'Arkansas'], ['CA', 'California'] ];
Then we can take this and use it to create a javascript object (/hash table) using Object.fromEntries(statesReversed)
so that we can use this to essentially "lookup" abbreviations and return full names.然后我们可以使用它并使用它使用Object.fromEntries(statesReversed)
创建一个 javascript 对象(/哈希表Object.fromEntries(statesReversed)
以便我们可以使用它来本质上“查找”缩写并返回全名。 We do this using:我们使用:
const statesConversionObject = Object.fromEntries(statesReversed); //which gives us: statesConversionObject = { AK: "Alaska", AL: "Alabama", AR: "Arkansas", AZ: "Arizona", CA: "California" }
This allows us to do this lookup like so:这允许我们像这样进行查找:
const statesDataModified = {}; for (let key in statesData){ const newKey = statesConversionObject[key]; statesDataModified[newKey] = statesData[key]; }
We get in return:我们得到回报:
statesDataModified = { 'Arizona': ['Some', 'Data'], 'Alabama': ['Some', 'Data'], 'Alaska': ['Some', 'Data'], 'Arkansas': ['Some', 'Data'], 'California': ['Some', 'Data'] };
Finally, convert to d3.map()
:最后,转换为d3.map()
:
const statesFullData = d3.map(statesDataModified);
You can easily create a new Map
object used for mapping states' abbreviations to their full names by passing a new copy of your states
array to the Map
constructor having keys and values reversed:通过将states
数组的新副本传递给具有反转键和值的Map
构造函数,您可以轻松创建一个新的Map
对象,用于将状态的缩写映射到它们的全名:
const statesMap = new Map(states.map(([name, abbr]) => [abbr, name]));
This acts as helper to resolve states' names when subsequently creating the new statesFullData
map from the statesData
map:这在随后从statesData
映射创建新的statesFullData
映射时充当解析状态名称的statesData
:
const statesFullData = new Map( // Create new map (full names-to-data) from...
Array.from( // ...array...
statesData, // ...from previous map (abbr-to-data)...
([abbr, data]) => [statesMap.get(abbr), data] // ...keys resolved to full name by abbreviation.
)
);
Have a look at the following snippet for a working demo:查看以下代码片段以获取工作演示:
const states = [ ['Arizona', 'AZ'], ['Alabama', 'AL'], ['Alaska', 'AK'], ['Arkansas', 'AR'], ['California', 'CA'], ]; const statesData = new Map([ ['AZ', "AZ data"], ['AL', "AL data"], ['AK', "AK data"], ['AR', "AR data"], ['CA', "CA data"], ]); const statesMap = new Map(states.map(([name, abbr]) => [abbr, name])); const statesFullData = new Map( Array.from( statesData, ([abbr, data]) => [statesMap.get(abbr), data] ) ); console.log(...statesFullData);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.