Проверьте, существуют ли ключи / узлы JSON - PullRequest
15 голосов
/ 15 июля 2009

Я использую API Google Map для получения информации о городе + штате / регионе из поиска по почтовому индексу. Проблема в том, что в некоторых случаях поиск по почтовому индексу не позволяет получить название города. Пример 92625 (США).

var g = new GClientGeocoder();
g.setBaseCountryCode('US');
g.getLocations('92625', function(response){
    if (response) {
        var place = response.Placemark[0];
        var state = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
        var city  = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
        GLog.write("City = "+city+" : State/Region = "+state+" : Country = " + g.getBaseCountryCode());
    }
});

В некоторых случаях, как упомянуто выше, в результате не будет названия города, поэтому для города возникнет неопределенная ошибка, поскольку ключ Locality не существует. Эта ошибка препятствует запуску остальной части скрипта.

Я смог исправить это с помощью ...

    if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality != null)
        var city  = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
    else
        var city = '';

... но у меня параноик по поводу подобной ошибки для других ключей. Например: если AdministrativeArea не определено, приведенный выше оператор IF также вызовет неопределенную ошибку. Так должен ли я проверить, существует ли каждый Ключ / Узел? Кажется, это грязный подход, потому что некоторые из этих ключей имеют глубину более 5 уровней ... Есть ли более простой способ сделать это, может быть, какой-то метод JQuery, с которым я не знаком?

Ответы [ 4 ]

9 голосов
/ 15 июля 2009

В качестве альтернативы, вы можете сделать функцию, которая дает вам значения по умолчанию:

function valueOrDefault(val, def) {
    if (def == undefined) def = "";
    return val == undefined ? def : val;
}

А затем используйте это так:

var place = response.Placemark[0];
var state = valueOrDefault(place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName);
var city  = valueOrDefault(place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName);

Лично я думаю, что написать немного приятнее, чем предложение p00ya, хотя это немного хакерски возиться с неопределенными объектами ... можно изменить его на следующее:

function drill(p, a) {
 a = a.split(".");//add this
 for (i in a) {
  var key = a[i];
  if (p[key] == null)
    return '';
  p = p[key];
 }
 return p;
}
var obj = {foo:{bar:{baz:"quux"}}};
var s = drill(obj, "foo.bar.baz"));//and you can use a simple property chain
3 голосов
/ 30 декабря 2012

Мне нравится подход back2dos, но я думаю, что его можно улучшить, чтобы не потерпеть неудачу с ReferenceError s:

function jPath(obj, a) {
    a = a.split(".");
    var p = obj||{};
    for (var i in a) {
        if (p === null || typeof p[a[i]] === 'undefined') return null;
        p = p[a[i]];
    }
    return p;
}

// Tests
var a = {b:{c:'Hello World!'}, c:null};

console.log(jPath(a, 'b.c'));   // Hello World
console.log(jPath(a, 'b.d'));   // null
console.log(jPath(a, 'e.f.g')); // null
console.log(jPath(a, 'c'));     // null

var z;
console.log(jPath(z, 'c'));     // null

Этот тип функций отлично подходит для проверки глубинных структур возврата JSON из сервисов AJAX, таких как freebase или YQL.

3 голосов
/ 15 июля 2009

Вы можете использовать функцию, которая «сверлит» все уровни вложенности, по умолчанию используя пустую строку, если она не может зайти так далеко.

function drill(p, a) {
 for (i in a) {
  var key = a[i];
  if (p[key] == null)
    return '';
  p = p[key];
 }
 return p;
}
var obj = {foo:{bar:{baz:"quux"}}};
var s = drill(obj, ["foo", "bar", "baz"]));
0 голосов
/ 15 июля 2009

Вы смотрите только на первый результат, который геокодер дает вам:

var place = response.Placemark[0];

getLocations () возвращает список из нескольких результатов. Если у первого его нет, один из следующих нескольких результатов почти наверняка будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...