【问题标题】:JS: convert array objects to dot stringJS:将数组对象转换为点字符串
【发布时间】:2019-12-17 09:16:42
【问题描述】:

我在数组中有嵌套对象,我想用 javascript 将它们转换为点符号字符串。

这是我用于转换过程的数据示例数据。

[
  {
    property: 'name',
    children: [],
    message: 'name should not be empty',
  },
  {
    property: 'priceForm',
    children: [
      {
        property: 'priceCurrency',
        children: [],
        message: 'priceCurrency should not be empty',
      },
    ],
  },
  {
    property: 'priceForm',
    children: [
      {
        property: 'rolePrices',
        children: [
          {
            property: '0',
            children: [
              {
                property: 'markupType',
                children: [],
                message: 'markupType should not be empty',
              },
            ],
          },
        ],
      },
    ],
  },
]

预期结果是

{
  'name': 'name should not be empty',
  'priceForm.priceCurrency': 'priceCurrency should not be empty',
  'priceForm.rolePrices.0.markupType': 'markupType should not be empty',
}

【问题讨论】:

  • 如果children 中的元素超过 1 个会怎样?
  • 例如 'priceForm.rolePrices.0.markupType1': 'markupType1 不应为空', 'priceForm.rolePrices.1.markupType2': 'markupType2 不应为空', 'priceForm.rolePrices .2.markupType3': 'markupType3 不能为空'

标签: javascript arrays object multidimensional-array nested


【解决方案1】:

您可以先收集路径,然后再构建属性。

function getObject(array, path = '', target = {}) {
    array.forEach(({ property, children = [], message }) => {
        var temp = path + (path && '.') + property;
        if (children.length) {
            getObject(children, temp, target);
            return;
        }
        target[temp] = message;
    });
    return target;   
}

var array = [{ property: 'name', children: [], message: 'name should not be empty' }, { property: 'priceForm', children: [{ property: 'priceCurrency', children: [], message: 'priceCurrency should not be empty' }] }, { property: 'priceForm', children: [{ property: 'rolePrices', children: [{ property: '0', children: [{ property: 'markupType', children: [], message: 'markupType should not be empty' }] }] }] }],
    object = getObject(array);
    
console.log(object);

【讨论】:

    【解决方案2】:

    你可以使用递归函数来格式化你想要的。

    const data = [{ property: 'name', children: [], message: 'name should not be empty' }, { property: 'priceForm', children: [{ property: 'priceCurrency', children: [], message: 'priceCurrency should not be empty' }] }, { property: 'priceForm', children: [{ property: 'rolePrices', children: [{ property: '0', children: [{ property: 'markupType', children: [], message: 'markupType should not be empty' }] }] }] }];
    
    let result = {};
    function format(data, prefix) {
        prefix = prefix ? `${prefix}.` : ''
        let message = ''
        data.forEach(i => {
            prefix = `${prefix}${i.property}`
            message = i.message
            if (!i.children.length) {
                i.message && (result[prefix] = i.message)
            } else {
                let child_data = format(i.children, prefix)
                child_data['message'] && child_data['prefix'] && (result[`${prefix}.${child_data['prefix']}`] = child_data['message'])
            }
            prefix = ''
        })
    
        return {prefix: prefix, message: message}
    }
    
    format(data)
    
    console.log(result)

    【讨论】:

    • 不是 OP 要求的输出。
    • 是的,我忘了清除prefix。现在可以了。谢谢:)
    【解决方案3】:

    给你! Array.reduce 和递归非常适合这个问题。

    const foo = (data, prefix = "") =>
      data.reduce(
        (acc, { property, message, children }) => ({
          ...acc,
          ...(children.length
            ? foo(children, `${prefix}${property}.`)
            : { [`${prefix}${property}`]: message })
        }),
        {}
      );
    
    const data = [
      {
        property: "name",
        children: [],
        message: "name should not be empty"
      },
      {
        property: "priceForm",
        children: [
          {
            property: "priceCurrency",
            children: [],
            message: "priceCurrency should not be empty"
          }
        ]
      },
      {
        property: "priceForm",
        children: [
          {
            property: "rolePrices",
            children: [
              {
                property: "0",
                children: [
                  {
                    property: "markupType",
                    children: [],
                    message: "markupType should not be empty"
                  },
                  {
                    property: "sibling!",
                    children: [],
                    message: "added a sibling to the input data"
                  }
                ]
              }
            ]
          }
        ]
      }
    ];
    
    
    console.log(foo(data));

    更新清理了一下。现在基本上是一个衬里? 也向输入数据添加了一个兄弟

    【讨论】:

      猜你喜欢
      • 2020-05-07
      • 2023-01-12
      • 2019-03-14
      • 2012-05-08
      • 2021-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多