【问题标题】:Changing nested object's structure更改嵌套对象的结构
【发布时间】:2020-10-17 14:54:03
【问题描述】:

我想将一个对象从一种格式转换为另一种格式。到目前为止,我递归执行此操作的尝试失败了;要么我得到最大堆栈异常,要么我无法遍历所有路径。

假设我们有一个列出问题及其答案的对象。可能有 N 个问题和 M 个答案。

开始时的对象:

var before = {
    item: 'Question 1',
    id: '1',
    type: 'Question',
    items: [
        {
            item: 'Answer 1',
            id: '1.1',
            type: 'Answer',
            items:
            [
                {
                    item: 'Question 2',
                    id: '1.1.1',
                    type: 'Question',
                    items: [
                        {
                            item: 'Answer 2.1',
                            id: '1.1.1.1',
                            type: 'Answer'
                        },
                        {
                            item: 'Answer 2.2',
                            id: '1.1.1.2',
                            type: 'Answer'
                        }
                    ]
                }   
                // ...          
            ]
        }, {
            item: 'Answer 1',
            id: '1.2',
            type: 'Answer',
            items:
            [
                {
                    item: 'Question 3',
                    id: '1.2.1',
                    type: 'Question',
                    items: [
                        {
                            item: 'Answer 3.1',
                            id: '1.2.1.1',
                            type: 'Answer'
                        },
                        {
                            item: 'Answer 3.2',
                            id: '1.2.1.2',
                            type: 'Answer'
                        }
                    ]
                }   
                // ...          
            ]
        }
        // ...
    ]
}

对象应该是什么样子(将所有内容包装在 'items' 数组中;将键名 'item' 更改为 'title','id' 更改为 'key',删除 'type',添加 'color' 取决于关于“类型”):

var after = {
    items: [
        {
            title: 'Question 1',
            key: '1',
            color: 'Red',
            items: [
                {
                    title: 'Answer 1',
                    key: '1.1',
                    color: 'Blue',
                    items:
                    [
                        {
                            title: 'Question 2',
                            key: '1.1.1',
                            color: 'Red',
                            items: [
                                {
                                    title: 'Answer 2.1',
                                    key: '1.1.1.1',
                                    color: 'Blue'
                                },
                                {
                                    title: 'Answer 2.2',
                                    key: '1.1.1.2',
                                    color: 'Blue'
                                }
                            ]
                        }   
                        // ...          
                    ]
                }, {
                    title: 'Answer 1',
                    key: '1.2',
                    color: 'Blue',
                    items:
                    [
                        {
                            title: 'Question 3',
                            key: '1.2.1',
                            color: 'Red',
                            items: [
                                {
                                    title: 'Answer 3.1',
                                    key: '1.2.1.1',
                                    color: 'Blue'
                                },
                                {
                                    title: 'Answer 3.2',
                                    key: '1.2.1.2',
                                    color: 'Blue'
                                }
                            ]
                        }   
                        // ...          
                    ]
                }
                // ...
            ]
        }
    ]
}

这似乎很容易,但我无法让它工作。这就是我尝试迭代的方式:

function iter(o) {
    for(let k in o) {
        if (!(['item', 'items', 'id'].includes(k))) // My object contains a few more keys I don't want to go down further into
            continue

        if (o[k] !== null && typeof o[k] === 'object') {
            iter(o[k]); // Max stack exception
            return;
        }
    }
};

非常感谢!

【问题讨论】:

    标签: javascript vue.js ecmascript-6


    【解决方案1】:

    您可以映射对象并重命名键并映射嵌套项。

    const
        iter = ({ item: title, id: key, type, items, ...o }) => ({
            title,
            key,
            color: 'color' + key,
            ...o,
            ...(items && { items: items.map(iter) })
        }),
        before = { item: 'Question 1', id: '1', type: 'Question', items: [{ item: 'Answer 1', id: '1.1', type: 'Answer', items: [{ item: 'Question 2', id: '1.1.1', type: 'Question', items: [{ item: 'Answer 2.1', id: '1.1.1.1', type: 'Answer' }, { item: 'Answer 2.2', id: '1.1.1.2', type: 'Answer' }] }] }, { item: 'Answer 1', id: '1.2', type: 'Answer', items: [{ item: 'Question 3', id: '1.2.1', type: 'Question', items: [{ item: 'Answer 3.1', id: '1.2.1.1', type: 'Answer' }, { item: 'Answer 3.2', id: '1.2.1.2', type: 'Answer' }] }] }] },
        result = [before].map(iter);
         
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      你可以使用map来实现,我写了一个简单的测试来说明我的观点here

      这是代码的重要部分

      function rename(item: any) {
        return {
          title: item.item,
          key: item.id,
          color: item.type === 'Question' ?  'red' : 'blue',
          items: item.items?.map(rename)
        }
      }
      
      console.log(items.map(rename))
      

      当然,如果您使用的是 typescript,请将 any 更改为适当的类型,并注意我使用的 ? 运算符不适用于 javascript,因此您可以执行类似的操作

      ...
      items: item.items ? item.items.map(rename) : undefined
      ... 
      

      【讨论】:

        猜你喜欢
        • 2019-03-15
        • 2022-01-17
        • 2021-07-14
        • 1970-01-01
        • 1970-01-01
        • 2020-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多