Получить информацию от JSON

1

У меня есть 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 
            }
        ]
    },
    ...

Тогда у меня есть две переменные: cs и rs. В любой момент только один из них отличается от нуля.

cs содержит страну, выбранную пользователем, rs содержит регион, выбранный пользователем. Как говорилось ранее, если cs отличается от нуля, то rs является нулевым и наоборот. Это связано с тем, что пользователь может выбрать страну на карте или выбрать регион страны.

Моя цель - создать флажок (или что-то подобное, мне все равно придется подумать об этом), который позволяет вам выбирать, помимо текущего региона (страны), и других регионов (стран), чтобы вы могли сравнивать данные.

Я бы хотел:

  • if cs != null → Я хочу получить список стран (все страны в файле Json)

  • если rs != null → Я хочу получить список регионов страны, к которой принадлежит rs.

Чтобы лучше понимать друг друга: Изображение 174551

Это то, что я пытался сделать.

// 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);

   });

}

Очевидно, что этот код не работает. Вернее, он работает для allCountries но не для currentRegions. Как я могу решить? Должен ли я использовать метод nest()?

Я хочу:

  • если cs != null → получить все страны
  • если rs != null → получить все регионы страны, к которой относится регион rs.

большое спасибо


Чтобы упростить, представьте, что у меня есть этот 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"
            }
        ]
    }
];

Затем у меня есть переменная, содержащая ginger. Как я могу получить список [cinnamon, ginger, salt]?

И если у меня есть переменная, содержащая строку Corbin, как мне получить список [Corbin, John]?

  • 0
    Есть ли проблема в доступе к элементу JSON?
  • 0
    Да, ты прав
Показать ещё 3 комментария
Теги:
d3.js

3 ответа

1
Лучший ответ

Хорошо, это требование требует, чтобы key был выбран на основе значения, и я придумал подход, который использует рекурсивный вызов (хотя могут быть и более эффективные подходы).

Шаги (упрощенные):

  1. Прокрутите массив. Позвольте вызывать элементы массива как row.
  2. Получить ключи row по Object.keys(row)
  3. Прокрутите все ключи внутри row.
  4. Если row[key] является объектом, просто найдите соответствующую пару ключ/значение, которая соответствует переданному value (главное значение - либо cs или rs), и возвращает соответствующий key. Я использовал инструкции break всем и, наконец, array.map() на основе связанного key.
  5. НО, если row[key] является массивом, используйте рекурсивный вызов и выполните описанные выше шаги.

Надеюсь, это объяснит код. Дайте знать, если у вас появятся вопросы. :)

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>
1

например, у меня есть пример массива json, такой же, как ваш json-массив:

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

и я должен получить доступ к возрастному свойству второго пользователя, тогда: users[1].age будут работать.

если вам нужно получить второй "favoriteFood" первого пользователя, тогда вы должны использовать: users[0].favoriteFoods[2].

по вашему запросу я собираюсь опубликовать еще один пример кода:

  • 0
    Спасибо, но мой файл JSON немного сложнее ...
  • 0
    Ваш JSON выглядит только большим, но он такой же, как я дал вам. как ваши "regions" похожи на favoriteFoods
Показать ещё 3 комментария
0

Основная проблема заключается в этом фрагменте кода:

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

Поскольку countrySelectedId всегда будет null если regionSelectedId имеет значение null, это выражение всегда будет возвращать false. Вам просто нужно изменить его на что-то полезное.

  • 0
    Это не правда, этот кусок кода работает :)
  • 0
    Каковы будут значения countrySelectedId и regionSelectedId которые вы используете?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню