简体   繁体   English

从JSON获取信息

[英]Get informations from JSON

I have a json file like this: 我有一个像这样的json文件:

[
    {
        "countryName": "Austria",
        "countryID": "AT",
        "countryPopulation": 8451860,
        "regions":[
            {
                "regionName": "Burgenland (AT)",
                "regionID": "AT11",
                "regionPopulation": 286691 
            },
            {
                "regionName": "Niederösterreich",
                "regionID": "AT12",
                "regionPopulation": 1618592
            },
            {
                "regionName": "Wien",
                "regionID": "AT13",
                "regionPopulation": 1741246
            },
            {
                "regionName": "Kärnten",
                "regionID": "AT21",
                "regionPopulation": 555473 
            },
            {
                "regionName": "Steiermark",
                "regionID": "AT22",
                "regionPopulation": 1210971 
            },
            {
                "regionName": "Oberösterreich",
                "regionID": "AT31",
                "regionPopulation": 1418498 
            },
            {
                "regionName": "Salzburg",
                "regionID": "AT32",
                "regionPopulation": 531898 
            },
            {
                "regionName": "Tirol",
                "regionID": "AT33",
                "regionPopulation": 715888  
            },
            {
                "regionName": "Vorarlberg",
                "regionID": "AT34",
                "regionPopulation": 372603 
            }
        ]
    },
    {
        "countryName": "Belgium",
        "countryID": "BE",
        "countryPopulation": 11161642,
        "regions":[
            {
                "regionName": "Région de Bruxelles-Capitale",
                "regionID": "BE10",
                "regionPopulation": 1174624 
            },
            {
                "regionName": "Prov. Antwerpen",
                "regionID": "BE21",
                "regionPopulation": 1802309  
            },
            {
                "regionName": "Prov. Limburg (BE)",
                "regionID": "BE22",
                "regionPopulation": 855963 
            },
            {
                "regionName": "Prov. Oost-Vlaanderen",
                "regionID": "BE23",
                "regionPopulation": 1465150  
            },
            {
                "regionName": "Prov. Vlaams-Brabant",
                "regionID": "BE24",
                "regionPopulation": 1103737  
            },
            {
                "regionName": "Prov. West-Vlaanderen",
                "regionID": "BE25",
                "regionPopulation": 1177567 
            },
            {
                "regionName": "Prov. Brabant Wallon",
                "regionID": "BE31",
                "regionPopulation": 389479  
            },
            {
                "regionName": "Prov. Hainaut",
                "regionID": "BE32",
                "regionPopulation": 1332489 
            },
            {
                "regionName": "Prov. Liège",
                "regionID": "BE33",
                "regionPopulation": 1095977
            },
            {
                "regionName": "Prov. Luxembourg (BE)",
                "regionID": "BE34",
                "regionPopulation": 278278 
            },
            {
                "regionName": "Prov. Namur",
                "regionID": "BE35",
                "regionPopulation": 486069 
            }
        ]
    },
    {
        "countryName": "Bulgaria",
        "countryID": "BG",
        "countryPopulation": 7284552,
        "regions":[
            {
                "regionName": "Severozapaden",
                "regionID": "BG31",
                "regionPopulation": 823469 
            },
            {
                "regionName": "Severen tsentralen",
                "regionID": "BG32",
                "regionPopulation": 844511 
            },
            {
                "regionName": "Severoiztochen",
                "regionID": "BG33",
                "regionPopulation": 957460 
            },
            {
                "regionName": "Yugoiztochen",
                "regionID": "BG34",
                "regionPopulation": 1067981 
            },
            {
                "regionName": "Yugozapaden",
                "regionID": "BG41",
                "regionPopulation": 2128783 
            },
            {
                "regionName": "Yuzhen tsentralen",
                "regionID": "BG42",
                "regionPopulation": 1462348 
            }
        ]
    },
    ...

Then I have two variables: cs and rs . 然后,我有两个变量: csrs At any moment only one of them is different from null. 在任何时候,它们中只有一个不同于null。

cs contains the country selected by the user, rs contains the region selected by the user. cs包含用户选择的国家, rs包含用户选择的国家。 As said before, if cs is different from null, then rs is null and vice versa. 如前所述,如果cs与null不同,则rs为null,反之亦然。 This is because the user can select a country from a map or select a region of a country. 这是因为用户可以从地图中选择国家或国家的区域。

My goal is to create a checkbox (or something similar, I still have to think about it) that allows you to select, beyond the current region (country), also other regions (countries) so you can compare data. 我的目标是创建一个复选框(或类似的东西,我仍然要考虑一下),该复选框使您可以选择当前区域(国家)之外的其他区域(国家),以便您可以比较数据。

What I would like is: 我想要的是:

  • if cs != null -> I want to get a list of countries (all countries in the Json file) 如果cs != null >我想获取国家列表(Json文件中的所有国家)

  • if rs != null -> I want to get the list of regions of the country to which the rs belongs. 如果rs != null >我想获取rs所属国家的地区列表。

To understand each other better: 互相了解: 在此处输入图片说明

This is what I tried to do. 这就是我试图做的。

// global variables
cs = null;  // if it is not null, the user has selected this country
csi = null; // country id
rs = null;  // if it is not null, the user has selected this region
rsi = null; // region id
currentCountries = null; // list of all countries
currentRegions = null; // list of regions in the selected country

/**
 * Function that creates line charts only when a country or a region is clicked.
 */
function createLineChart(antigenSelected, yearSelected, countrySelected, countrySelectedId, regionSelected, regionSelectedId) {
   defineLines(antigenSelected, yearSelected, countrySelected, countrySelectedId, regionSelected, regionSelectedId);
}

function defineLines(antigenSelected, yearSelected, countrySelected, countrySelectedId, regionSelected, regionSelectedId) {
   /**
    * To know if the user has clicked on the country or region, check that the selected region belongs to the selected country:
    *   - if it belongs to us -> the user has clicked on the selected region
    *   - if it does not belong to us -> the user has clicked on the selected country.
    * At any moment only one of the two possibilities is assigned (the other is null).
    */
   cs = null;  // if it is not null, the user has selected this country
   csi = null; // country id
   rs = null;  // if it is not null, the user has selected this region
   rsi = null; // region id

   // if the user has selected a region
   if(regionSelectedId != null && countrySelectedId == regionSelectedId.substring(0, 2)) {
      rs = regionSelected;
      rsi = regionSelectedId;
   }
   // if the user has selected a country
   else {
      cs = countrySelected;
      csi = countrySelectedId;
   }

   console.log("countrySelected: " + cs);
   console.log("regionSelected: " + rs);

   /**
    * Load json with countries and regions.
    */
   d3.json("../Project2/data/json/countriesAndRegions.json", function(error, countriesAndRegions) {
      if(error) {
         console.log("*** ERROR LOADING FILES: " + error + " ***");
         throw error;
      }

      countriesAndRegions.forEach(function(c) {
         allCountries.push(c.countryName);
         currentRegions = c.regions;
      });

      currentRegions.forEach(function(r) {
         //console.log(r.regionName);
      });

      console.log(allCountries);
      console.log(currentRegions);

      //var nested = d3.nest()
         // I have to nest data?
         //.object(currentRegions);

   });

}

Obviously this code doesn't work. 显然,此代码不起作用。 Or rather, it works for allCountries but not for currentRegions . 或者说,它适用于allCountries但不适用于currentRegions How can I solve? 我该如何解决? Should I use the nest() method? 我应该使用nest()方法吗?

What I want is: 我想要的是:

  • if cs != null -> get all countries 如果cs != null >获取所有国家
  • if rs != null -> get all regions of the country to which the rs region belongs. 如果rs != null >获取rs区域所属国家的所有区域。

Thanks a lot 非常感谢


To simplify, imagine that I have this json file. 为了简化,假设我有这个json文件。

var users = [
    {
        name: 'Corbin',
        age: 20,
        favoriteFoods: ['ice cream', 'pizza'],
        other: [
            {
                a: 12,
                b: "apple"
            }, 
            {
                a: 15,
                b: "pear"
            }
        ]
    },
    {
        name: 'John',
        age: 25,
        favoriteFoods: ['ice cream', 'skittle'],
        other: [
            {
                a: 0,
                b: "cinnamon"
            }, 
            {
                a: 854,
                b: "ginger"
            }, 
            {
                a: 24,
                b: "salt"
            }
        ]
    }
];

Then I have a variable that contains the string ginger . 然后我有一个包含字符串ginger的变量。 How can I get the list [cinnamon, ginger, salt] ? 如何获得清单[cinnamon, ginger, salt]

And if I have a variable containing the string Corbin , how do I get the list [Corbin, John] ? 如果我有一个包含字符串Corbin的变量,如何获取列表[Corbin, John]

for example I have a json array sample same as your json array: 例如我有一个与您的json数组相同的json数组示例:

var users = [{name: 'Corbin', age: 20, favoriteFoods: ['ice cream', 'pizza']},
             {name: 'John', age: 25, favoriteFoods: ['ice cream', 'skittle']}];

and i have to access the age property of the second user, then: users[1].age will work. 并且我必须访问第二个用户的age属性,然后: users[1].age将起作用。

if you have to access the second "favoriteFood" of the first user then you should use: users[0].favoriteFoods[2] . 如果必须访问第一个用户的第二个“ favoriteFood”,则应使用: users[0].favoriteFoods[2]

according to you request i am going to post an another sample code: 根据您的要求,我将发布另一个示例代码:

Okay this requirement requires the key to be fetched based on the value and I've come up with an approach that uses a recursive call (there might be better approaches though). 好的,此要求要求根据值来获取key ,并且我想出了一种使用递归调用的方法(不过可能有更好的方法)。

Steps ( simplified ): 步骤( 简化 ):

  1. Loop through an array. 遍历数组。 Let's call the elements of array as a row . 让我们将array的元素称为row
  2. Get row keys by Object.keys(row) 通过Object.keys(row)获取row
  3. Loop through all the keys within the row . 循环浏览该row所有键。
  4. If row[key] is an object, just find the appropriate key/value pair that matches the value passed (main value - either cs or rs ) and return the associated key . 如果row[key]是一个对象,只需找到与传递的value (主值-cs或rs )匹配的适当的键/值对,然后返回关联的key I've used break statements all over and finally a array.map() based on the associated key . 我已经使用了break语句,最后使用了基于关联keyarray.map()
  5. BUT if row[key] is an Array , use the recursive call and perform the above steps. 但是,如果row[key]是一个Array ,请使用递归调用并执行上述步骤。

Hope this explains the code. 希望这能解释代码。 Let me know if you have any questions. 如果您有任何疑问,请告诉我。 :) :)

 var data = [ { "countryName": "Austria", "countryID": "AT", "countryPopulation": 8451860, "regions":[ { "regionName": "Burgenland (AT)", "regionID": "AT11", "regionPopulation": 286691 }, { "regionName": "Niederösterreich", "regionID": "AT12", "regionPopulation": 1618592 }, { "regionName": "Wien", "regionID": "AT13", "regionPopulation": 1741246 }, { "regionName": "Kärnten", "regionID": "AT21", "regionPopulation": 555473 }, { "regionName": "Steiermark", "regionID": "AT22", "regionPopulation": 1210971 }, { "regionName": "Oberösterreich", "regionID": "AT31", "regionPopulation": 1418498 }, { "regionName": "Salzburg", "regionID": "AT32", "regionPopulation": 531898 }, { "regionName": "Tirol", "regionID": "AT33", "regionPopulation": 715888 }, { "regionName": "Vorarlberg", "regionID": "AT34", "regionPopulation": 372603 } ] }, { "countryName": "Belgium", "countryID": "BE", "countryPopulation": 11161642, "regions":[ { "regionName": "Région de Bruxelles-Capitale", "regionID": "BE10", "regionPopulation": 1174624 }, { "regionName": "Prov. Antwerpen", "regionID": "BE21", "regionPopulation": 1802309 }, { "regionName": "Prov. Limburg (BE)", "regionID": "BE22", "regionPopulation": 855963 }, { "regionName": "Prov. Oost-Vlaanderen", "regionID": "BE23", "regionPopulation": 1465150 }, { "regionName": "Prov. Vlaams-Brabant", "regionID": "BE24", "regionPopulation": 1103737 }, { "regionName": "Prov. West-Vlaanderen", "regionID": "BE25", "regionPopulation": 1177567 }, { "regionName": "Prov. Brabant Wallon", "regionID": "BE31", "regionPopulation": 389479 }, { "regionName": "Prov. Hainaut", "regionID": "BE32", "regionPopulation": 1332489 }, { "regionName": "Prov. Liège", "regionID": "BE33", "regionPopulation": 1095977 }, { "regionName": "Prov. Luxembourg (BE)", "regionID": "BE34", "regionPopulation": 278278 }, { "regionName": "Prov. Namur", "regionID": "BE35", "regionPopulation": 486069 } ] }, { "countryName": "Bulgaria", "countryID": "BG", "countryPopulation": 7284552, "regions":[ { "regionName": "Severozapaden", "regionID": "BG31", "regionPopulation": 823469 }, { "regionName": "Severen tsentralen", "regionID": "BG32", "regionPopulation": 844511 }, { "regionName": "Severoiztochen", "regionID": "BG33", "regionPopulation": 957460 }, { "regionName": "Yugoiztochen", "regionID": "BG34", "regionPopulation": 1067981 }, { "regionName": "Yugozapaden", "regionID": "BG41", "regionPopulation": 2128783 }, { "regionName": "Yuzhen tsentralen", "regionID": "BG42", "regionPopulation": 1462348 } ] } ]; var cs = 'Belgium', rs = 'Yuzhen tsentralen'; // cs is not null, get all countries but first find the key var mainKey = null; function getKey(array, value) { for(var i=0; i<array.length; i++) { var flag = false, row = array[i], keys = Object.keys(row); for(var j=0; j<keys.length; j++) { var key = keys[j]; if(Array.isArray(row[key])) { getKey(row[key], value); } else if(row[key] === value) { mainKey = key; flag = true; console.log(array.map(function(d) { return d[mainKey];})); break; } } if(flag) { break; } } } if(cs != null) { getKey(data, cs); } if(rs != null) { getKey(data, rs); } /******************** This is what I thought earlier about the requirement, use it if you find it helpful *************/ /* // with underscore.js var row = _.findWhere(data, {countryName: cs}); if(row) { console.log(row["regions"]); console.log(row["regions"].map(function(r) { return r["regionName"]; })); } // without underscore.js var index = null; for(var i=0; i<data.length; i++) { if(data[i]['countryName'] === cs) { index = i; break; } } console.log(data[index]["regions"]); console.log(data[index]["regions"].map(function(r) { return r["regionName"]; })); */ 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 

The main problem is in this piece of code: 主要问题在这段代码中:

regionSelectedId != null && countrySelectedId == regionSelectedId.substring(0, 2)

Since countrySelectedId will always be null when regionSelectedId is null , that expression will always return false. 由于当regionSelectedIdnullcountrySelectedId将始终为null ,因此该表达式将始终返回false。 You just have to modify it into something useful. 您只需要将其修改为有用的内容即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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