Более эффективный способ извлечения адресных компонентов
В настоящее время я использую следующий код, чтобы получить страну, почтовый индекс, местонахождение и подкатегорию:
var country, postal_code, locality, sublocality;
for (i = 0; i < results[0].address_components.length; ++i)
{
for (j = 0; j < results[0].address_components[i].types.length; ++j)
{
if (!country && results[0].address_components[i].types[j] == "country")
country = results[0].address_components[i].long_name;
else if (!postal_code && results[0].address_components[i].types[j] == "postal_code")
postal_code = results[0].address_components[i].long_name;
else if (!locality && results[0].address_components[i].types[j] == "locality")
locality = results[0].address_components[i].long_name;
else if (!sublocality && results[0].address_components[i].types[j] == "sublocality")
sublocality = results[0].address_components[i].long_name;
}
}
Это неудовлетворительно. Есть ли другой способ добиться того же результата?
Ответы
Ответ 1
if (typeof Object.keys == 'function')
var length = function(x) { return Object.keys(x).length; };
else
var length = function() {};
var location = {};
for (i = 0; i < results[0].address_components.length; ++i)
{
var component = results[0].address_components[i];
if (!location.country && component.types.indexOf("country") > -1)
location.country = component.long_name;
else if (!location.postal_code && component.types.indexOf("postal_code") > -1)
location.postal_code = component.long_name;
else if (location.locality && component.types.indexOf("locality") > -1)
location.locality = component.long_name;
else if (location.sublocality && component.types.indexOf("sublocality") > -1)
location.sublocality = component.long_name;
// nothing will happen here if `Object.keys` isn't supported!
if (length(location) == 4)
break;
}
Это самое подходящее решение для меня. Это может помочь кому-то тоже.
Ответ 2
Вы можете использовать следующую функцию для извлечения любого компонента адреса:
function extractFromAdress(components, type){
for (var i=0; i<components.length; i++)
for (var j=0; j<components[i].types.length; j++)
if (components[i].types[j]==type) return components[i].long_name;
return "";
}
Чтобы извлечь информацию, которую вы вызываете:
var postCode = extractFromAdress(results[0].address_components, "postal_code");
var street = extractFromAdress(results[0].address_components, "route");
var town = extractFromAdress(results[0].address_components, "locality");
var country = extractFromAdress(results[0].address_components, "country");
и т.д...
Ответ 3
Вы можете сократить его до
var country, postal_code, locality, sublocality;
for (i = 0; i < results[0].address_components.length; ++i) {
var component = results[0].address_components[i];
if (!sublocality && component.types.indexOf("sublocality") > -1)
sublocality = component.long_name;
else if (!locality && component.types.indexOf("locality") > -1)
locality = component.long_name;
else if (!postal_code && component.types.indexOf("postal_code") > -1)
postal_code = component.long_name;
else if (!country && component.types.indexOf("country") > -1)
country = component.long_name;
}
Или вы пытаетесь получить лучший отформатированный результат? Тогда, пожалуйста, покажите нам свой запрос.
Ответ 4
Моя однострочная линия с использованием функционального подхода и map
, filter
и ES2015:
/**
* Get the value for a given key in address_components
*
* @param {Array} components address_components returned from Google maps autocomplete
* @param type key for desired address component
* @returns {String} value, if found, for given type (key)
*/
function extractFromAddress(components, type) {
return components.filter((component) => component.types.indexOf(type) === 0).map((item) => item.long_name).pop() || null;
}
Использование:
const place = autocomplete.getPlace();
const address_components = place["address_components"] || [];
const postal_code = extractFromAddress("postal_code");
Ответ 5
Я сделал это вот так:
placeParser = function(place){
result = {};
for(var i = 0; i < place.address_components.length; i++){
ac = place.address_components[i];
result[ac.types[0]] = ac.long_name;
}
return result;
};
то я просто использую
parsed = placeParser(place)
parsed.route
Ответ 6
Я действительно считаю, что user1429980 ответ выше заслуживает большего признания. Он работает очень хорошо. Мой ответ основан на его функции. Я добавил несколько примеров, чтобы лучше показать, как искать объект JSON, используя код user1429980 при условии:
//searches object for a given key and returns the key value
extractFromObject (object, key) {
return object.filter((object) => component.types.indexOf(key)
=== 0).map((item)=>item.long_name).pop() || null;
}
Пример 1: Google reverseGeocode API с долготой и широтой, установленный в 43.6532,79.3832 (Торонто, Онтарио, Канада):
var jsonData = {} //object contains data returned from reverseGeocode API
var city = extractFromObject(jsonData.json.results[0].address_components, 'locality');
console.log(city); //Output is Toronto
Пример 2: API Google Адресов с идентификатором места, установленным для ChIJE9on3F3HwoAR9AhGJW_fL-I (Лос-Анджелес, Калифорния, США):
var jsonData = {} //object contains data returned from Google Places API
var city = extractFromObject(jsonData.json.result.address_components, 'locality');
console.log(city); //Output is Los Angeles
Ответ 7
Используя lodash
const result = _.chain(json.results[0].address_components)
.keyBy('types[0]')
.mapValues('short_name')
.value()
Ответ 8
Посетители, использующие underscore.js, могут легко преобразовать массив address_components
в ответе геокода в литерал объекта:
var obj = _.object(
_.map(results[0].address_components, function(c){
return [c.types[0], c.short_name]
})
);