【问题标题】:How to convert square bracket object keys from URL location into nested object in Javascript?如何将方括号对象键从 URL 位置转换为 Javascript 中的嵌套对象?
【发布时间】:2015-06-13 09:11:28
【问题描述】:

与:

var obj = { "object[foo][bar][ya]": 100 };

如何创建:

var obj = { object: { foo: { bar: { ya: 100 }}}};

【问题讨论】:

    标签: javascript angularjs url


    【解决方案1】:

    手动方法

    用括号分割给定的字符串,然后遍历生成的标记以生成嵌套对象:

    给定

    var obj = { "object[foo][bar][ya]": 100 };
    

    拆分它们,我们得到

    var tokens = Object.keys(obj)[0]
        .split('[')
        .map(function(s){return s.replace(']','')});
        // tokens = [ 'object', 'foo', 'bar', 'ya' ]
    

    然后制作嵌套对象,由内而外

    var result = {};
    tokens.reverse().forEach(function(key){
        if (Object.keys(result).length==0){
            result[key] = obj[Object.keys(obj)[0]]; // inner-most key-value
        }
        else{
            var temp = {};
            temp[key] = result;
            result = temp;
        }
    });
    

    结果

    {"object":{"foo":{"bar":{"ya":100}}}}

    【讨论】:

    • 这不是一个非常强大的解决方案,但是非常聪明的方法 +1
    • @cyrbil 任何建议表示赞赏:) 我一直想听听人们的想法。
    【解决方案2】:

    在 javascript fr 解析查询字符串中的嵌套对象时,它们不是原生的东西。

    您可以使用http://medialize.github.io/URI.js/,这非常适合这项工作。

    console.log(URI.parseQuery("?&foo=bar&&foo=bar&foo=baz&"));
    

    如果您不想导入完整的库,这只是查询字符串解析的部分(完全归功于https://github.com/medialize/URI.js):

    var URI = {
      decodeQuery: function(string, escapeQuerySpace) {
        string += '';
    
        try {
          return decodeURIComponent(escapeQuerySpace ? string.replace(/\+/g, '%20') : string);
        } catch(e) {
          // we're not going to mess with weird encodings,
          // give up and return the undecoded original string
          // see https://github.com/medialize/URI.js/issues/87
          // see https://github.com/medialize/URI.js/issues/92
          return string;
        }
      },
      parseQuery: function(string, escapeQuerySpace) {
        if (!string) {
          return {};
        }
    
        // throw out the funky business - "?"[name"="value"&"]+
        string = string.replace(/&+/g, '&').replace(/^\?*&*|&+$/g, '');
    
        if (!string) {
          return {};
        }
    
        var items = {};
        var splits = string.split('&');
        var length = splits.length;
        var v, name, value;
    
        for (var i = 0; i < length; i++) {
          v = splits[i].split('=');
          name = URI.decodeQuery(v.shift(), escapeQuerySpace);
          // no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters
          value = v.length ? URI.decodeQuery(v.join('='), escapeQuerySpace) : null;
    
          if (Object.prototype.hasOwnProperty.call(items, name)) {
            if (typeof items[name] === 'string') {
              items[name] = [items[name]];
            }
    
            items[name].push(value);
          } else {
            items[name] = value;
          }
        }
    
        return items;
      }
    };
    

    【讨论】:

      【解决方案3】:

      您可以获取零件并构建一个新对象。

      const obj = {
          "object[foo][bar][ya]": 100,
          "object[foo][baz]": 200,
          "object[foo][bar][bar]": 50,
          "xy": 30
      };
      
      let newObj = {};
      
      for (const i in obj) {
          let a = i.match(/([^\[\]]+)(\[[^\[\]]+[^\]])*?/g),
              p = obj[i];
              j = a.length;
      
          while (j--) {
              q = {};
              q[a[j]] = p;
              p = q;
          }
          // merge object
          let k = Object.keys(p)[0],
              o = newObj;
      
          while (k in o) {
              p = p[k];
              o = o[k];
              k = Object.keys(p)[0];
          }
      
          o[k] = p[k];
      }
      
      console.log(newObj);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        【解决方案4】:

        这是一个 es6 版本。注意:尚未针对极端情况进行测试。

        const keyPattern = /^(\w+)\[(\w+)\](.*)$/;
        
        export function decodeParams(params) {
          return Object.keys(params).reduce((result, key) => {
            let match = key.match(keyPattern);
        
            if (match && match.length >= 3) {
              let [key, nextKey, rest = ''] = match.slice(1);
        
              result[key] = Object.assign(
                {},
                result[key],
                decodeParams({ [nextKey + rest]: params[key] })
              );
            } else {
              result[key] = params[key];
            }
        
            return result;
          }, {});
        }
        

        【讨论】:

          猜你喜欢
          • 2011-12-09
          • 1970-01-01
          • 2020-07-07
          • 2015-12-07
          • 2019-12-27
          • 2018-01-24
          • 1970-01-01
          相关资源
          最近更新 更多