【问题标题】:Filter the array of object have the same nested property in javascript过滤对象数组在javascript中具有相同的嵌套属性
【发布时间】:2020-06-30 15:03:12
【问题描述】:
[{"code":"96","value":"RemoveTest","parentLabelCode":1,"color":null,"level":1,"children":[{"code":"97","value":"R1","parentLabelCode":96,"color":null,"level":2,"children":[],"visible":true,"retired":false,"systemLabel":true,"removeOnArchive":true,"displayNumber":1,"labelTranslations":null},{"code":"98","value":"R2","parentLabelCode":96,"color":null,"level":2,"children":[],"visible":true,"retired":true,"systemLabel":true,"removeOnArchive":true,"displayNumber":2,"labelTranslations":null},{"code":"99","value":"R3","parentLabelCode":96,"color":null,"level":2,"children":[],"visible":true,"retired":true,"systemLabel":true,"removeOnArchive":true,"displayNumber":2,"labelTranslations":null}],"visible":true,"retired":false,"systemLabel":true,"removeOnArchive":true,"displayNumber":0,"labelTranslations":null}]

我想要这个输出:基于退休的过滤器:假,退休:真,不应该显示并且有多个对象并且有深度嵌套的孩子我正在递归地做,但没有得到预期的输出

 var list = label_lists.filter(function f(item) {
            return item.retired==false ||
            item.children && (item.children = item.children.filter(f)).length
          })

[{"code":"96","value":"RemoveTest","parentLabelCode":1,"color":null,"level":1,"children":[{"code":"97","value":"R1","parentLabelCode":96,"color":null,"level":2,"children":[],"visible":true,"retired":false,"systemLabel":true,"removeOnArchive":true,"displayNumber":1,"labelTranslations":null}],"visible":true,"retired":false,"systemLabel":true,"removeOnArchive":true,"displayNumber":0,"labelTranslations":null}]

【问题讨论】:

    标签: javascript


    【解决方案1】:

    这是一个递归解决方案,它也复制而不是修改源对象:

    function notRetired(arr) {
        return arr.filter(item => !item.retired)
            .map(item => Object.assign({}, item, {
                children: notRetired(item.children)
            }));
    }
    

    这是一个适用于循环结构的(略显老套的)变体:

    function notRetired(arr, cache = null) {
        return arr.filter(item => !item.retired)
            .map((item, ret) => (cache || (cache = new Map())).get(item) ||
                (cache.set(item, ret = {}) && Object.assign(ret, item, {
                    children: notRetired(item.children, cache)
                })));
    }
    

    【讨论】:

    • 好:我没有看到having the same nested property。显然,行动不关心退休人员的活跃孩子。正如他所说的retired : true , should not be display
    • Uncaught RangeError: Maximum call stack size exceeded
    • 听起来你可能有一个循环结构,你的源数据数组是如何构建的?在创建数据结构时进行过滤可能会更好,尽管如果不可行,有一些方法可以减轻递归函数中的堆栈溢出。
    【解决方案2】:

    您正在过滤以下人员:未退休 (item.retired==false) (||) 有孩子 (item.children ) (&&) 他们的孩子都没有退休 (item.children = item.children.filter(f)).length)

    我认为您希望包括儿童在内的所有人给我所有未退休的。对吗?

    var label_lists = [{
        "code":"96","value":"RemoveTest","parentLabelCode":1,"color":null,"level":1,
        "children":[{
            "code":"97","value":"R1","parentLabelCode":96,"color":null,"level":2,"children":[],"visible":true,"retired":false,"systemLabel":true,"removeOnArchive":true,"displayNumber":1,"labelTranslations":null
        }],
        "visible":true,"retired":false,"systemLabel":true,"removeOnArchive":true,"displayNumber":0,"labelTranslations":null}];
    
    function filterActive(dic) {
        return dic.retired==false ? dic : [];
    }
    
    function findAll(array) {
        var res = [];
        for (item of array) {
            res.push(filterActive(item));
            res = res.concat(findAll(item.children));
        }
        return res;
    }
    
    console.log(findAll(label_lists));
    

    --->

    [ { code: '96',
        value: 'RemoveTest',
        parentLabelCode: 1,
        color: null,
        level: 1,
        children: [ [Object] ],
        visible: true,
        retired: false,
        systemLabel: true,
        removeOnArchive: true,
        displayNumber: 0,
        labelTranslations: null },
      { code: '97',
        value: 'R1',
        parentLabelCode: 96,
        color: null,
        level: 2,
        children: [],
        visible: true,
        retired: false,
        systemLabel: true,
        removeOnArchive: true,
        displayNumber: 1,
        labelTranslations: null } ]
    

    关于函数式编程的注意事项。你的意图确实不错。但是根据您的问题,您想更改列表的结构。请注意,过滤器在任何情况下都只能减小列表大小。 reduce 是适合您的激光剑。

    先把它写成循环和函数,然后数组上的任何循环都可以改成mapfilterreduce

    顺便欢迎SO

    【讨论】:

    • 嗨@tinmarino,如果已退休,这将给所有子项作为空白:false 不需要它具有真或假,并且在父数组中它的所有子项只需要已退休的子项: false,需要弹出才能看到我的输入输出
    • 基本不需要pop过滤器
    • 是的,它会使列表变平。 Mike 解决方案更好,您必须增加堆栈大小。 stackoverflow.com/questions/20936486/…
    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 2022-01-24
    • 2021-05-16
    • 2018-01-16
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    相关资源
    最近更新 更多