从 serializeArray 创建嵌套对象

Create nested object from serializeArray

我想创建这个结构:

{
    "officine_type": "Pharmacie",
    "officine_value": 2002626,
    "declared_lines": [
                          {
                             "ean": 3578835501148,
                             "qty": 1
                           },
                           {
                             "ean": 3578835502671,
                             "qty": 2
                           }
                       ],
    "other_value": "my other value"
}

来自具有此输出的 serializeArray():

0: {name: 'declared_lines.0.ean', value: '3578835502244'}
1: {name: 'declared_lines.0.qty', value: '4'}
2: {name: 'declared_lines.1.ean', value: '3578835502220'}
3: {name: 'declared_lines.1.qty', value: '1'}
4: {name: 'declared_lines.2.ean', value: ''}
5: {name: 'declared_lines.2.qty', value: '0'}
6: {name: 'officine_type', value: 'Pharmacy'}
7: {name: 'officine_value', value: '2000461'}
8: {name: 'other_value', value: ''}

我正在为如何在 declared_lines

中推送子对象而苦恼

现在我有这个:

let formData = form.serializeArray();

  for (let i = 0; i < formData.length; i++) {
    if (formData[i]['name'].indexOf('declared_lines') !== 1) {
      let inputName = formData[i]['name'].split('.');
      let namespace = inputName[0];
      let n = inputName[1];
      let key = inputName[2];
      let subObj = {};
      let current = 'declared_lines['+i+']';
      let previous = 'declared_lines['+(i-1)+']';

      if (obj.hasOwnProperty(namespace) === false) {
        obj[namespace] = [];
      }
    }
    obj[formData[i]['name']] = formData[i]['value'];
  }

我的脑子不会更进一步:(

您可以获取名称并用点将其拆分为新对象的路径和值,然后使用给定的信息构建一个新对象。

setValue中,reduce 回调检查下一个键是否为字符串数值,并将数组作为默认对象而不是对象。

function setValue(object, path, value) {
    const last = path.pop();

    path
        .reduce((o, k, i, kk) => o[k] ??= (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}), object)
        [last] = value;

    return object;
}

const
    data = [{ name: 'declared_lines.0.ean', value: '3578835502244' }, { name: 'declared_lines.0.qty', value: '4' }, { name: 'declared_lines.1.ean', value: '3578835502220' }, { name: 'declared_lines.1.qty', value: '1' }, { name: 'declared_lines.2.ean', value: '' }, { name: 'declared_lines.2.qty', value: '0' }, { name: 'officine_type', value: 'Pharmacy' }, { name: 'officine_value', value: '2000461' }, { name: 'other_value', value: '' }],
    result = data.reduce(
        (object, { name, value }) => setValue(object, name.split('.'), value),
        {}
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Object destructuring and array.reduce可以让你的代码更具可读性,试试:

let formData = [
   {name: 'declared_lines.0.ean', value: '3578835502244'},
   {name: 'declared_lines.0.qty', value: '4'},
   {name: 'declared_lines.1.ean', value: '3578835502220'},
   {name: 'declared_lines.1.qty', value: '1'},
   {name: 'declared_lines.2.ean', value: ''},
   {name: 'declared_lines.2.qty', value: '0'},
   {name: 'officine_type', value: 'Pharmacy'},
   {name: 'officine_value', value: '2000461'},
   {name: 'other_value', value: ''}
];

let output = formData.reduce((acc,cur) => {
   let { name, value } = cur;
   if(name.indexOf('declared_lines') === -1){
      acc[name] = value;
   } else {
      let [namespace, n, key] = name.split('.');
      if(!acc[namespace]) acc[namespace] = [];
      if(!acc[namespace][n]) acc[namespace][n] = {};
      acc[namespace][n][key] = value;
   }
   return acc;
}, {});

console.log(output);

在这种情况下,reduce 从一个空对象开始,它遍历您的数组以处理每个元素 (cur)。