【问题标题】:How to update value of nested array of objects如何更新嵌套对象数组的值
【发布时间】:2017-09-22 13:10:42
【问题描述】:

这是我的实际数组:

let mainArray= [
    {
        value: '/AG_TURF-123',
        label: 'Ag & Turf',
        checked: false,
        id:123,
        children: [
            {
                value: '/AG_TURF-123/TRACTOR-456',
                label: 'Tractors',
                checked: false,
                id:456,
                children: [
                    {
                        value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series',
                        label: 'Large (7, 8, 9) Series',
                        checked: false,
                        id:789,
                        children: [{
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/7-family-tractor',
                            label: '7 Family Tractor',
                            checked: false,
                            id:101112
                        },{
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/8-family-tractor',
                            label: '8 Family Tractor',
                            checked: false,
                            id:131415
                        },{
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/9-family-tractor',
                            label: '9 Family Tractor',
                            checked: false,
                            id:161718
                        }],
                    },
                    {
                        value: '/app/Http/routes.js',
                        label: 'routes.js',
                        checked: false,
                        id:181920
                    },
                ],
            },
            {
                value: '/app/Providers',
                label: 'Providers',
                checked: false,
                id:212223,
                children: [{
                    value: '/app/Http/Providers/EventServiceProvider.js',
                    label: 'EventServiceProvider.js',
                    checked: false,
                    id:242526
                }],
            },
        ],
    },
    {
        value: '/config',
        label: 'config',
        checked: false,
        id:272829,
        children: [
            {
                value: '/config/app.js',
                label: 'app.js',
                checked: false,
                id:303132
            },
            {
                value: '/config/database.js',
                label: 'database.js',
                checked: false,
                id:333435
            },
        ],
    },
    {
        value: '/public',
        label: 'public',
        checked: false,
        id:353637,
        children: [
            {
                value: '/public/assets/',
                label: 'assets',
                checked: false,
                id:383940,
                children: [{
                    value: '/public/assets/style.css',
                    label: 'style.css',checked: false,
                    id:404142
                }],
            },
            {
                value: '/public/index.html',
                label: 'index.html',
                checked: false,
                id: 434445
            },
        ],
    },
    {
        value: '/.env',
        label: '.env',
        checked: false,
        id: 464748
    },
    {
        value: '/.gitignore',
        label: '.gitignore',
        checked: false,
        id: 495051
    },
    {
        value: '/README.md',
        label: 'README.md',
        checked: false,
        id: 525354
    },
];

这是我的价值清单:

const ids=[525354,123,131415];

如果 id 匹配,我想将 checked 设置为 true。 我的主阵列可能有 6 到 7 步深。

到目前为止我做了什么:

setCheckedFlagToItems(checkList, items) {
        return items.map((item) => {
            const node = item;
            if (checkList.indexOf(node.id) !== -1) {
                node.checked = true;
            }
            if ((node.children) && (Array.isArray(node.children) && node.children.length > 0)) {
                this.setCheckedFlagToItems(checkList, node.children);
            }
            return node;
        }, this);
    }

但它没有像往常一样工作。

【问题讨论】:

    标签: javascript arrays loops recursion


    【解决方案1】:

    您可以使用带有命名函数的迭代和递归方法作为Array#forEach 的回调。

    let mainArray = [
    {
        value: '/AG_TURF-123', 
        label: 'Ag & Turf', 
        checked: false, 
        id: 123, 
        children: [
            { 
                value: '/AG_TURF-123/TRACTOR-456', 
                label: 'Tractors', 
                checked: false, 
                id: 456, 
                children: [
                    { 
                        value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series', 
                        label: 'Large (7, 8, 9) Series', 
                        checked: false, 
                        id: 789, 
                        children: [
                            { 
                                value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/7-family-tractor', 
                                label: '7 Family Tractor', 
                                checked: false, 
                                id: 101112 
                            }, 
                            { 
                                value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/8-family-tractor', 
                                label: '8 Family Tractor', 
                                checked: false, 
                                id: 131415 
                            }, 
                            { 
                                value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/9-family-tractor', 
                                label: '9 Family Tractor', 
                                checked: false, 
                                id: 161718 
                            }
                        ] 
                    }, 
                    {
                        value: '/app/Http/routes.js', 
                        label: 'routes.js', 
                        checked: false, 
                        id: 181920 
                    }
                ]
            }, 
            { 
                value: '/app/Providers', 
                label: 'Providers', 
                checked: false, 
                id: 212223, 
                children: [
                    { 
                        value: '/app/Http/Providers/EventServiceProvider.js', 
                        label: 'EventServiceProvider.js', 
                        checked: false, 
                        id: 242526 
                    }
                ]
            }
        ]
    }, 
    {
        value: '/config', 
        label: 'config', 
        checked: false, 
        id: 272829, 
        children: [
            {
                value: '/config/app.js', 
                label: 'app.js', 
                checked: false, 
                id: 303132
            },
            {
                value: '/config/database.js', 
                label: 'database.js', 
                checked: false, 
                id: 333435 
            }
        ]
    }, 
    {
        value: '/public', 
        label: 'public', 
        checked: false, 
        id: 353637, 
        children: [
            {
                value: '/public/assets/', 
                label: 'assets', 
                checked: false, 
                id: 383940, 
                children: [
                    {
                        value: '/public/assets/style.css', 
                        label: 'style.css', 
                        checked: false, 
                        id: 404142
                    }
                ]
            }, 
            {
                value: '/public/index.html', 
                label: 'index.html', 
                checked: false, 
                id: 434445 
            }
        ] 
    }, 
    { 
        value: '/.env', 
        label: '.env', 
        checked: false, 
        id: 464748 
    }, 
    { 
        value: '/.gitignore', 
        label: '.gitignore', 
        checked: false, 
        id: 495051 
    }, 
    { 
        value: '/README.md', 
        label: 'README.md', 
        checked: false, 
        id: 525354 
    }
    ],
        ids = [525354, 123, 131415];
    
    mainArray
        .forEach(
            function iter(a) {
                if (ids.includes(a.id)) {
                    a.checked = true;
                }
                Array.isArray(a.children) && a.children.forEach(iter);
            }
        );
    
    console.log(mainArray);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • @Kris Hollenbeck,您的编辑并没有真正检查数组是否为递归迭代,这是必要的。
    • 嗯.. 也许我看错了。它在我的 IDE 中引发错误。旧代码是Array.isArray( (a.children) && a.children.forEach(callback); .. 我得到了) 的预期。所以缺少括号。
    • 也许应该是Array.isArray( a.children) && a.children.forEach(iter);
    • ^^ 它看起来像原来的......并且是有意的。
    • 是的,你的权利。我猜这是一个 tslint 错误。对于那个很抱歉。 imgur.com/a/hRMAI
    【解决方案2】:

    如果您的 ids 是“唯一的”(每个 id 属性只有一个唯一对象),您还可以将此操作分为两个步骤:

    1. 创建一个新的数据结构,将所有项目扁平化为id: item 的一个对象
    2. 循环通过ids 以从该对象中检索项目。

    如果您发现自己通过 id 查找许多对象,则创建此临时表示可能更容易。

    地图的创建使用类似于其他答案的递归:只要item 包含children 数组,它就会在返回之前将它们添加到地图对象中。

    const mainArray = [{ value: '/AG_TURF-123', label: 'Ag & Turf', checked: false, id: 123, children: [{ value: '/AG_TURF-123/TRACTOR-456', label: 'Tractors', checked: false, id: 456, children: [{ value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series', label: 'Large (7, 8, 9) Series', checked: false, id: 789, children: [{ value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/7-family-tractor', label: '7 Family Tractor', checked: false, id: 101112 }, { value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/8-family-tractor', label: '8 Family Tractor', checked: false, id: 131415 }, { value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/9-family-tractor', label: '9 Family Tractor', checked: false, id: 161718 }] }, { value: '/app/Http/routes.js', label: 'routes.js', checked: false, id: 181920 }] }, { value: '/app/Providers', label: 'Providers', checked: false, id: 212223, children: [{ value: '/app/Http/Providers/EventServiceProvider.js', label: 'EventServiceProvider.js', checked: false, id: 242526 }] }] }, { value: '/config', label: 'config', checked: false, id: 272829, children: [{ value: '/config/app.js', label: 'app.js', checked: false, id: 303132 }, { value: '/config/database.js', label: 'database.js', checked: false, id: 333435 }] }, { value: '/public', label: 'public', checked: false, id: 353637, children: [{ value: '/public/assets/', label: 'assets', checked: false, id: 383940, children: [{ value: '/public/assets/style.css', label: 'style.css', checked: false, id: 404142 }] }, { value: '/public/index.html', label: 'index.html', checked: false, id: 434445 }] }, { value: '/.env', label: '.env', checked: false, id: 464748 }, { value: '/.gitignore', label: '.gitignore', checked: false, id: 495051 }, { value: '/README.md', label: 'README.md', checked: false, id: 525354 }];
    
    // We reduce the array of nested items in to one object of:
    // { id: item }
    const idMap = mainArray.reduce(function merge(map, node) {
      map[node.id] = node;
      
      if (Array.isArray(node.children)) {
        node.children.reduce(merge, map);
      }
      
      return map;
    }, {});
    
    const ids = [525354, 123, 131415];
    
    // Whenever you need an item, you can get it
    // using idMap[id]
    const items = ids.map(id => idMap[id]);
    items.forEach(item => item.checked = true);
    
    // or: ids.forEach(id => idMap[id].checked = true)

    【讨论】:

      猜你喜欢
      • 2021-11-27
      • 1970-01-01
      • 2021-02-06
      • 2023-01-12
      • 2023-01-23
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多