0

我有这个 Javascript 对象(由我的插件代码即时创建):

{
   "field": {
      "name": "Name",
      "surname": "Surname"
   },
   "address": {
      "street": "Street",
      "number": 0,
      "postcode": 0,
      "geo": {
        "city": "City",
        "country": "Country",   
        "state": "State"   
      }
   },
   "options": [1,4,6,8,11]
 }

不想将此对象转换为 JSON 字符串,但我想将此对象转换为另一个对象,但每个字段都由字符串表示,如下所示:

{
  "field[name]": "Name",
  "field[surname]": "Surname",
  "address[street]": "Street",
  "address[number]": 0,
  "address[postcode]": 0,
  "address[geo][city]": "City",
  "address[geo][country]": "Country",   
  "address[geo][state]": "State",   
  "options[0]":1,
  "options[1]":4,
  "options[2]":6,
  "options[3]":8,
  "options[4]":11
}

设想:

  • 我不知道原始对象会是什么样子(或者它会有多深),因为它是插件的一部分,我不知道人们将如何构建他们的表单
  • 我要把这个新对象放在一个FormData对象里面,如果它只接受对象,那就更容易了,因为JSON不能上传文件,但FormData对象可以
4

2 回答 2

3

正如我在评论中所说,您需要一个for...in [MDN]循环来迭代对象的属性,并且可以使用递归来随后转换嵌套对象:

function convert(obj, prefix, result) {
    result = result || {};

    // iterate over all properties
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            var value = obj[prop];
            // build the property name for the result object
            // first level is without square brackets
            var name = prefix ? prefix + '[' + prop + ']' : prop;
            if (typeof value !== 'object') {
                // not an object, add value to final result
                result[name] = value;
            }
            else {
                // object, go deeper
                convert(value, name, result);
            }
        }
    }

    return result;
}

// Usage:
var converted_data = convert(data);

演示

不过,我还是建议使用 JSON。

如果您还想处理文件,则可能必须添加额外的File对象检查。您希望它们在结果对象中是原始的:

else if (window.File && value instanceof File) {
    result[name] = value;
}

// and for file lists

else if (window.FileList && value instanceof FileList) {
    for (var i = 0, l = value.length; i < l; i++) {
        result[name + '[' + i + ']'] = value.item(i);
    }
}

可能是File( FileList) 构造函数在 IE 中的名称不同,但它应该让您有一个开始。

于 2013-01-20T13:56:53.200 回答
0

不是重新发明轮子的忠实粉丝,所以这里是您如何使用object-scan回答您的问题。它是一个很好的数据处理工具——一旦你把头绕在它周围,那就是。

// const objectScan = require('object-scan');

const convert = (haystack) => objectScan(['**'], {
  filterFn: ({ key, value, isLeaf, context }) => {
    if (isLeaf) {
      const k = key.map((e, idx) => (idx === 0 ? e : `[${e}]`)).join('');
      context[k] = value;
    }
  }
})(haystack, {});

const data = { field: { name: 'Name', surname: 'Surname' }, address: { street: 'Street', number: 0, postcode: 0, geo: { city: 'City', country: 'Country', state: 'State' } }, options: [1, 4, 6, 8, 11] };

console.log(convert(data));
/* =>
  { 'options[4]': 11,
    'options[3]': 8,
    'options[2]': 6,
    'options[1]': 4,
    'options[0]': 1,
    'address[geo][state]': 'State',
    'address[geo][country]': 'Country',
    'address[geo][city]': 'City',
    'address[postcode]': 0,
    'address[number]': 0,
    'address[street]': 'Street',
    'field[surname]': 'Surname',
    'field[name]': 'Name' }
*/
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.7.1"></script>

免责声明:我是对象扫描的作者

于 2020-11-18T02:34:37.803 回答