简体   繁体   English

D3 v4 如何同步迭代数据

[英]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.eacharray.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']
};
  1. 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'] ];
  2. 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" }
  3. This allows us to do this lookup like so:这允许我们像这样进行查找:

     const statesDataModified = {}; for (let key in statesData){ const newKey = statesConversionObject[key]; statesDataModified[newKey] = statesData[key]; }
  4. We get in return:我们得到回报:

     statesDataModified = { 'Arizona': ['Some', 'Data'], 'Alabama': ['Some', 'Data'], 'Alaska': ['Some', 'Data'], 'Arkansas': ['Some', 'Data'], 'California': ['Some', 'Data'] };
  5. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM