如何在 Javascript 中将方括号对象键从 URL 位置转换为嵌套对象

How to convert square bracket object keys from URL location into nested object in Javascript?

本文关键字:对象 URL 位置 转换 嵌套 Javascript 方括号      更新时间:2023-09-26

With:

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

如何创建:

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

手动方法

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

鉴于

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

}

它们在 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;
  }
};

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

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

这是一个 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;
  }, {});
}