У меня есть 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.
Чтобы лучше понимать друг друга:
Это то, что я пытался сделать.
// 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]
?
Хорошо, это требование требует, чтобы key
был выбран на основе значения, и я придумал подход, который использует рекурсивный вызов (хотя могут быть и более эффективные подходы).
Шаги (упрощенные):
row
.row
по Object.keys(row)
row
.row[key]
является объектом, просто найдите соответствующую пару ключ/значение, которая соответствует переданному value
(главное значение - либо cs или rs), и возвращает соответствующий key
. Я использовал инструкции break
всем и, наконец, array.map() на основе связанного key
.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>
например, у меня есть пример массива 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]
.
по вашему запросу я собираюсь опубликовать еще один пример кода:
"regions"
похожи на favoriteFoods
Основная проблема заключается в этом фрагменте кода:
regionSelectedId != null && countrySelectedId == regionSelectedId.substring(0, 2)
Поскольку countrySelectedId
всегда будет null
если regionSelectedId
имеет значение null
, это выражение всегда будет возвращать false. Вам просто нужно изменить его на что-то полезное.
countrySelectedId
и regionSelectedId
которые вы используете?