如何从与每个数组有关系的对象数组中删除对象?

时间:2018-02-06 07:46:29

标签: javascript arrays angularjs algorithm recursion

此对象的关系为: childOne > childTwo > childThree > childFour > childFive >的 childSix

{
  "parentObj": {
    "childOne": [
      {
        "name": "A",
        "id": "1"
      },
      {
        "name": "B",
        "id": "2"
      }
    ],
    "childTwo": [
      {
        "name": "AB",
        "parent_id": "1",
        "id": "11"
      },
      {
        "name": "DE",
        "parent_id": "2",
        "id": "22"
      }
    ],
    "childThree": [
      {
        "name": "ABC",
        "parent_id": "22",
        "id": "111"
      },
      {
        "name": "DEF",
        "parent_id": "11",
        "id": "222"
      }
    ],
    "childFour": [
      {
        "name": "ABCD",
        "parent_id": "111",
        "id": "1111"
      },
      {
        "name": "PQRS",
        "parent_id": "111",
        "id": "2222"
      }
    ],
    "childFive": [
      {
        "name": "FGRGF",
        "parent_id": "1111",
        "id": "11111"
      },
      {
        "name": "ASLNJ",
        "parent_id": "1111",
        "id": "22222"
      },
      {
        "name": "ASKJA",
        "parent_id": "1111",
        "id": "33333"
      }
    ],
    "childSix": [
      {
        "name": "SDKJBS",
        "parent_id": "11111",
        "id": "111111"
      },
      {
        "name": "ASKLJB",
        "parent_id": "11111",
        "id": "222222"
      }
    ]
  }
}

有没有办法按ID删除项目,并且与该特定ID相关联的对象应该被删除(即,如果我delete parentObj.childTwo[1],那么它下面的所有相关对象也应该被删除)

手动循环代码太糟糕,并产生错误。必须有更好的方法来处理递归或其他类型的问题。

3 个答案:

答案 0 :(得分:0)

当然,用于删除条目的函数应该首先递归,这意味着在链接条目上运行自己,除非没有。所以,在psuedocode

function del(name, index)
{
    if parent[name][index]  has reference
    Then del(reference name, reference ID)
    Now del parent[name][index] 
}

不需要循环。 如果我们没有参考就停止了,我们就不会永远地归还。

答案 1 :(得分:0)

不确定你想要什么,但也许这会奏效:

const someObject = {
  "parentObj": {
    "childOne": [
      {
        "name": "A",
        "id": "1"
      },
      {
        "name": "B",
        "id": "2"
      }
    ],
    "childTwo": [
      {
        "name": "AB",
        "childOne": "1",
        "id": "11"
      },
      {
        "name": "DE",
        "childOne": "2",
        "id": "22"
      }
    ]
  }
};
const removeByID = (key,id,parent) =>
  Object.keys(parent).reduce(
    (o,k)=>{
      o[k]=parent[k].filter(
        item=>
          !(Object.keys(item).includes(key)&&item[key]===id)
      );
      return o;
    },
    {}
  );

const withoutID = Object.assign(
  {},
  someObject,
  { parentObj : removeByID("childOne","1",someObject.parentObj) }
);
console.log(`notice that childTwo item with childOne:"1" is gone`);
console.log("without key:",JSON.stringify(withoutID,undefined,2));

const otherExample = Object.assign(
  {},
  someObject,
  { parentObj : removeByID("childOne","2",someObject.parentObj) }
);
console.log(`notice that childTwo item with childOne:"2" is gone`);
console.log("without key:",JSON.stringify(otherExample,undefined,2));

const both = Object.assign(
  {},
  someObject,
  { parentObj : removeByID("childOne","1",otherExample.parentObj) }
);
console.log(`notice that childTwo items with childOne are both gone`);
console.log("without key:",JSON.stringify(both,undefined,2));

答案 2 :(得分:0)

数据结构不允许有效操作:

  • 自然对象具有非有序的属性集,因此无法保证迭代parentObj的属性将为您提供childOnechildTwo,{{1实际上,这个顺序是由创建这些属性的顺序决定的,但没有文件证明。所以有人可能会在父母面前找到孩子,反之亦然。
  • 虽然一个此类childThree数组中的id值应该是唯一的,但此对象结构并不能保证这一点。此外,给定某个child值,不可能在恒定时间内找到相应的对象。

鉴于这种结构,最好先添加一个哈希来解决上述缺点。知道节点组(通过id)和对象知道哪个是下一级别的组名称的对象可以帮助解决这个问题。

上述两个任务可以在 O(n)时间执行,其中 n 是节点数。

这是与ES5兼容的代码(因为您在评论中提到没有ES6支持)。它提供了一个示例调用,其中从示例数据中删除了ID为“1111”的节点,并打印出结果对象。

id
function removeSubTree(data, id) {
    var groupOf = {}, groupAfter = {}, group, parents, keep = { false: [], true: [] };

    // Provide link to group per node ID
    for (group in data) {
        data[group].forEach(function (node) {
            groupOf[node.id] = group;
        });
    }
    // Create ordered sequence of groups, since object properties are not ordered
    for (group in data) {
        if (!data[group].length || !data[group][0].parent_id) continue;
        groupAfter[groupOf[data[group][0].parent_id]] = group;
    }
    // Check if given id exists:
    group = groupOf[id];
    if (!group) return; // Nothing to do
    // Maintain list of nodes to keep and not to keep within the group
    data[group].forEach(function (node) {
        keep[node.id !== id].push(node);
    });
    while (keep.false.length) { // While there is something to delete
        data[group] = keep.true; // Delete the nodes from the group
        if (!keep.true.length) delete data[group]; // Delete the group if empty
        // Collect the ids of the removed nodes
        parents = {};
        keep.false.forEach(function (node) {
            parents[node.id] = true;
        });
        group = groupAfter[group]; // Go to next group
        if (!group) break; // No more groups
        // Determine what to keep/remove in that group
        keep = { false: [], true: [] };
        data[group].forEach(function (node) {
            keep[!parents[node.parent_id]].push(node);
        });
    }
}

var tree = {"parentObj": {"childOne": [{"name": "A","id": "1"},{"name": "B","id": "2"}],"childTwo": [{"name": "AB","parent_id": "1","id": "11"},{"name": "DE","parent_id": "2","id": "22"}],"childThree": [{"name": "ABC","parent_id": "22","id": "111"},{"name": "DEF","parent_id": "11","id": "222"}],"childFour": [{"name": "ABCD","parent_id": "111","id": "1111"},{"name": "PQRS","parent_id": "111","id": "2222"}],"childFive": [{"name": "FGRGF","parent_id": "1111","id": "11111"},{"name": "ASLNJ","parent_id": "1111","id": "22222"},{"name": "ASKJA","parent_id": "1111","id": "33333"}],"childSix": [{"name": "SDKJBS","parent_id": "11111","id": "111111"},{"name": "ASKLJB","parent_id": "11111","id": "222222"}]}}

removeSubTree(tree.parentObj, "1111");

console.log(tree.parentObj);

相关问题