【问题标题】:Remove object from array inside a recursive function从递归函数内的数组中删除对象
【发布时间】:2020-06-12 01:46:53
【问题描述】:

我有以下模型对象:

const model = {
    _id: '1',
    children: [
        {
            id: '2',
            isCriteria: true
        },
        {
            id: '3',
            isCriteria: true
        }
    ]
}

PS:children的深度是未知的,所以我必须使用递归函数来导航。

我想根据 ids 数组从子数组中删除特定对象。
因此,例如,如果进行以下调用 removeCriteria(model, ['2']),结果应该是:

const model = {
    _id: '1',
    children: [
        {
            id: '2',
            isCriteria: true
        }
    ]
}

我实现了这个功能如下:

function removeCriteria(node, criteria, parent = []) {
    if (node.isCriteria) {
        if (criteria.length && !criteria.includes(node.id)) {
            parent = parent.filter(criteria => criteria.id !== node.id);
        }
        console.log(parent) // here the parents object is correct but it doesn't modify the original object
    }
    if (node.children)
        for (const child of node.children) removeCriteria(child, criteria, node.children);
}

【问题讨论】:

  • removeCriteria(model, ['2']) 的结果不应该是id 3 的对象吗?
  • @awarrier99 不,我想保留给定数组中存在的对象。
  • 也许你应该重命名你的函数keepCriteria
  • @Nick 但我正在删除基于数组的条件,该数组上不存在的条件将被删除。
  • 不,你是对的,这根本不是问题,但通常人们将一个值传递给一个想要删除而不是保留的 remove 函数。

标签: javascript arrays object recursion


【解决方案1】:

分配给parent 不会分配给值来自的对象属性。

您需要过滤 node.children 并分配回该属性。

function removeCriteria(node, criteria) {
  if (criteria.length == 0) {
    return;
  }
  if (node.children) {
    node.children = node.children.filter(child => !child.isCriteria || criteria.includes(child.id));
    node.children.forEach(child => removeCriteria(child, criteria));
  }
}
const model = {
  _id: '1',
  children: [{
      id: '2',
      isCriteria: true
    },
    {
      id: '3',
      isCriteria: true
    }
  ]
}

removeCriteria(model, ['2']);
console.log(model);

【讨论】:

    【解决方案2】:

    问题是您正在重新分配变量parent,它不会完成任何事情,因为您没有改变数组以删除对象,而是将其分配给新创建的数组。我建议引入parentObjparent 所属对象的引用,这样您就可以将parentObj.children 设置为parent 并实际改变原始对象的数组属性:

    const model = {
        _id: '1',
        children: [
            {
                id: '2',
                isCriteria: true
            },
            {
                id: '3',
                isCriteria: true
            }
        ]
    };
    
    function removeCriteria(node, criteria, parent = [], parentObj = {}) {
        if (node.isCriteria) {
            if (criteria.length && !criteria.includes(node.id)) {
                parent = parent.filter(criteria => criteria.id !== node.id);
                parentObj.children = parent;
            }
            console.log('parent', parent) // here the parents object is correct but it doesn't modify the original object
        }
        if (node.children)
            for (const child of node.children) removeCriteria(child, criteria, node.children, node);
    }
    
    removeCriteria(model, ['2']);
    console.log(model);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-28
      • 2021-04-24
      • 1970-01-01
      相关资源
      最近更新 更多