【问题标题】:More efficient way to extract address components提取地址组件的更有效方法
【发布时间】:2012-01-08 23:26:15
【问题描述】:

目前,我正在使用以下代码来获取国家/地区、邮政编码、地区和次地区:

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;
    }
}

这不令人满意。有没有其他方法可以达到同样的效果?

【问题讨论】:

    标签: javascript google-maps google-maps-api-3


    【解决方案1】:

    您可以使用以下函数来提取任何地址组件:

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

    等等……

    【讨论】:

    • locality 和 route 不再起作用,你有解决办法吗?
    • 感谢您的解决方案,我已经对其进行了修改并为我工作。 this.editedItem.Province = this.extractFromAdress(data.results[0].address_components, "administrative_area_level_1"); this.editedItem.District = this.extractFromAdress(data.results[0].address_components, "administrative_area_level_2"); this.editedItem.Neighborhood = this.extractFromAdress(data.results[0].address_components, "administrative_area_level_4");
    【解决方案2】:

    我的单线使用函数式方法和mapfilter 和 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(address_components, "postal_code");
    

    【讨论】:

    • 这太棒了。很有效
    • 非常有才华的ans.it很有帮助
    【解决方案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】:

    我是这样做的:

    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
    

    【讨论】:

      【解决方案5】:

      使用lodash

      const result = _.chain(json.results[0].address_components)
        .keyBy('types[0]')
        .mapValues('short_name')
        .value()
      

      【讨论】:

        【解决方案6】:

        我真的相信上面的user1429980 答案值得更多的认可。它真的很好用。我的回答是基于他的功能。我添加了一些示例以更好地说明如何使用提供的代码 user1429980 搜索 JSON 对象:

        //searches object for a given key and returns the key's value

        extractFromObject (object, key) { return object.filter((component) => 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:Google 的 Places API,地点 ID 设置为 ChIJE9on3F3HwoAR9AhGJW_fL-I(美国加利福尼亚州洛杉矶):

        var jsonData = {} //object contains data returned from Google's Places API

        var city = extractFromObject(jsonData.json.result.address_components, 'locality');

        console.log(city); //Output is Los Angeles

        【讨论】:

          【解决方案7】:

          使用 underscore.js 的访问者可以轻松地将地理编码响应中的 address_components 数组转换为对象字面量:

          var obj = _.object( 
              _.map(results[0].address_components, function(c){ 
                  return  [c.types[0], c.short_name] 
              })
          );
          

          【讨论】:

            【解决方案8】:
            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;
            }
            

            这是最适合我的解决方案。它也可能对某人有所帮助。

            【讨论】:

              【解决方案9】:

              在给定地点类型列表的情况下,我在此之前创建了一个函数:

              const getValue = function(data, types=[]){
              /* used by results taken from Geocoder.geocode api */
              const values = data.reduce((values, address) => {
                  return address.address_components.reduce((values2, component) => {
                      if(component.types.reduce((result, type) => result || types.indexOf(type) > -1, false))
                          values2.push(component.long_name);
                      return values2
                  }, []);
              
                  if(buff.length)
                      return [...values, ...buff];
                  return values;
              }, []).filter(
                  (value, index, self) => {
                      return self.indexOf(value) === index;
                  }
              );
              

              }

              【讨论】:

                猜你喜欢
                • 2019-01-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-06-29
                • 2010-10-07
                • 2014-12-19
                • 2011-01-22
                • 2015-08-30
                相关资源
                最近更新 更多