【问题标题】:JS: Remove object from nested array and return parent arrayJS:从嵌套数组中删除对象并返回父数组
【发布时间】:2017-06-19 16:39:57
【问题描述】:

如何删除嵌套在另一个数组中的数组 subBrands 中的对象,其中对象的 id 属性为 = 31。我正在尝试在不删除该子品牌的情况下取回整个父数组。

数组是:

[
  {
    "id": 10,
    "name": "Parent Brand 1",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 09:55:51",
    "updated_at": "2017-02-02 09:55:51",
    "subBrands": [
      {
        "id": 31,
        "name": "Sub Brand 6",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:24:49",
        "updated_at": "2017-02-02 11:42:02"
      },
      {
        "id": 32,
        "name": "Sub Brand 7",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:24:57",
        "updated_at": "2017-02-02 11:42:18"
      },
      {
        "id": 33,
        "name": "Sub Brand 8",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:25:04",
        "updated_at": "2017-02-02 11:42:34"
      },
      {
        "id": 34,
        "name": "Sub Brand 9",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:25:39",
        "updated_at": "2017-02-02 11:42:43"
      },
      {
        "id": 35,
        "name": "Sub Brand 10",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:25:46",
        "updated_at": "2017-02-02 11:42:52"
      },
      {
        "id": 36,
        "name": "Sub Brand 4",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:43:53",
        "updated_at": "2017-02-02 11:43:53"
      }
    ]
  },
  {
    "id": 12,
    "name": "Parent Brand 2",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 09:56:16",
    "updated_at": "2017-02-02 09:56:16",
    "subBrands": []
  },
  {
    "id": 16,
    "name": "Brand no children",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 10:37:40",
    "updated_at": "2017-02-02 10:37:40",
    "subBrands": []
  },
  {
    "id": 37,
    "name": "Whoops brand",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 11:44:10",
    "updated_at": "2017-02-02 11:44:10",
    "subBrands": []
  }
]

我想要得到的是:

[
  {
    "id": 10,
    "name": "Parent Brand 1",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 09:55:51",
    "updated_at": "2017-02-02 09:55:51",
    "subBrands": [
      {
        "id": 32,
        "name": "Sub Brand 7",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:24:57",
        "updated_at": "2017-02-02 11:42:18"
      },
      {
        "id": 33,
        "name": "Sub Brand 8",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:25:04",
        "updated_at": "2017-02-02 11:42:34"
      },
      {
        "id": 34,
        "name": "Sub Brand 9",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:25:39",
        "updated_at": "2017-02-02 11:42:43"
      },
      {
        "id": 35,
        "name": "Sub Brand 10",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:25:46",
        "updated_at": "2017-02-02 11:42:52"
      },
      {
        "id": 36,
        "name": "Sub Brand 4",
        "parent": 10,
        "author": 1,
        "deleted_at": null,
        "created_at": "2017-02-02 11:43:53",
        "updated_at": "2017-02-02 11:43:53"
      }
    ]
  },
  {
    "id": 12,
    "name": "Parent Brand 2",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 09:56:16",
    "updated_at": "2017-02-02 09:56:16",
    "subBrands": []
  },
  {
    "id": 16,
    "name": "Brand no children",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 10:37:40",
    "updated_at": "2017-02-02 10:37:40",
    "subBrands": []
  },
  {
    "id": 37,
    "name": "Whoops brand",
    "parent": null,
    "author": 1,
    "deleted_at": null,
    "created_at": "2017-02-02 11:44:10",
    "updated_at": "2017-02-02 11:44:10",
    "subBrands": []
  }
]

我愿意使用下划线。我最接近的是:

    var brands = _.filter(brands, function(n) { 
        return _.some(n.subBrands, function(subBrand){ 
            return subBrand.id != brand.id;
        });
    });

但这会删除不包含 id 为 31 的子品牌的数组。所以它不是很接近我需要的。

干杯!

【问题讨论】:

  • 它应该适用于任何深度吗?还是只为第二级?
  • @NinaScholz 目前我只需要第二级。希望不再需要它。
  • “我正在尝试在不删除子品牌的情况下取回整个父数组。”您的意思是删除了对象吗?
  • @guest271314 没有 ID 为 31 的子品牌,整个事情都不会回来。第二个数组是我试图找回的示例。
  • @BarryWalsh 是的,您是否要从 subBrands 数组中删除带有 id 31 的对象?

标签: javascript arrays object filter


【解决方案1】:

var arr = [{"id":10,"name":"Parent Brand 1","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 09:55:51","updated_at":"2017-02-02 09:55:51","subBrands":[{"id":31,"name":"Sub Brand 6","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:24:49","updated_at":"2017-02-02 11:42:02"},{"id":32,"name":"Sub Brand 7","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:24:57","updated_at":"2017-02-02 11:42:18"},{"id":33,"name":"Sub Brand 8","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:25:04","updated_at":"2017-02-02 11:42:34"},{"id":34,"name":"Sub Brand 9","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:25:39","updated_at":"2017-02-02 11:42:43"},{"id":35,"name":"Sub Brand 10","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:25:46","updated_at":"2017-02-02 11:42:52"},{"id":36,"name":"Sub Brand 4","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:43:53","updated_at":"2017-02-02 11:43:53"}]},{"id":12,"name":"Parent Brand 2","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 09:56:16","updated_at":"2017-02-02 09:56:16","subBrands":[]},{"id":16,"name":"Brand no children","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 10:37:40","updated_at":"2017-02-02 10:37:40","subBrands":[]},{"id":37,"name":"Whoops brand","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:44:10","updated_at":"2017-02-02 11:44:10","subBrands":[]}];


var id = prompt("Id of subbrands to remove: ");

arr.forEach(function(o) {
  o.subBrands = o.subBrands.filter(s => s.id != id);
});

console.log(arr);

【讨论】:

  • 您通过过滤数组来创建所有新的引用。为此目的,这看起来有点过头了,即使没有具有所需 id 的对象,您也会产生一个新数组。
  • 为什么每次迭代都要在.forEach()创建一个新数组,而要求是从现有数组中删除一个对象?
  • @NinaScholz @guest271314 如果您认为唯一的其他方法是在每个找到的元素上调用forEachsplice,这将是最好的。
  • @ibrahimmahrir “如果您认为唯一的其他方法是在每个找到的元素上调用 forEachsplice,这将是最好的。”不是唯一的其他可能的方法。那是您选择使用的模式。 “最好”是什么意思?无需创建新数组即可达到从现有数组中删除对象的预期结果。
  • @BarryWalsh,我不知道,如果我是合适的人,我的建议如下,但无论如何你需要一个原始数组和另一个没有特定 ID 的数组吗?还是只有一个?
【解决方案2】:

您可以迭代父部分和子部分,如果找到则拼接对象。

var data = [{ id: 10, name: "Parent Brand 1", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 09:55:51", updated_at: "2017-02-02 09:55:51", subBrands: [{ id: 31, name: "Sub Brand 6", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:24:49", updated_at: "2017-02-02 11:42:02" }, { id: 32, name: "Sub Brand 7", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:24:57", updated_at: "2017-02-02 11:42:18" }, { id: 33, name: "Sub Brand 8", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:25:04", updated_at: "2017-02-02 11:42:34" }, { id: 34, name: "Sub Brand 9", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:25:39", updated_at: "2017-02-02 11:42:43" }, { id: 35, name: "Sub Brand 10", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:25:46", updated_at: "2017-02-02 11:42:52" }, { id: 36, name: "Sub Brand 4", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:43:53", updated_at: "2017-02-02 11:43:53" }] }, { id: 12, name: "Parent Brand 2", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 09:56:16", updated_at: "2017-02-02 09:56:16", subBrands: [] }, { id: 16, name: "Brand no children", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 10:37:40", updated_at: "2017-02-02 10:37:40", subBrands: [] }, { id: 37, name: "Whoops brand", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 11:44:10", updated_at: "2017-02-02 11:44:10", subBrands: [] }];

data.some(function (a) {
    return a.subBrands.some(function (b, i, bb) {
        if (b.id === 31) {
            bb.splice(i, 1);
            return true;
        }
    });
});

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这将仅删除包含它们的第一个找到的对象的匹配子品牌。考虑arr = [{sb: [id:31]}, {sb: [id:31]}, {sb: [id:31]}] 将仅删除some 找到的第一个对象。
  • @ibrahimmahrir,我假设所有id 都是独一无二的。无需过滤所有子数组。这会生成新的引用,这是不必要的。保护环境。
  • 我不是在谈论 subBrands 数组本身(那些 ID 应该是唯一的)。我说的是包含 subBrand 数组的不同对象。
  • 另外,这不是some 的典型用法。它应该仅用于检查项目是否符合某些条件(作为其他内容的前瞻)。
  • @ibrahimmahrir “另外,这不是 some 的典型用法。它应该仅用于检查项目是否符合某些条件(作为其他内容的前瞻)。”我> ? “应该使用”是什么意思?对不同任务使用Array.prototype 方法没有任何限制。
【解决方案3】:

我嵌套了两个forEach 循环,并在找到并删除该项目时返回:

let items = [{id: 1, subItems: [{id: 1}, {id: 2}]}];

const subItemToBeRemovedId = 1;

items.forEach((item) => item.subItems.forEach((subItem, index) => {
    if (subItem.id === subItemToBeRemovedId) {
        return item.subItems.splice(index, 1);
    }
}));

console.log(items);

【讨论】:

    【解决方案4】:

    foreach 似乎有效:

    var brands=[{id:10,name:"Parent Brand 1",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 09:55:51",updated_at:"2017-02-02 09:55:51",subBrands:[{id:31,name:"Sub Brand 6",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:24:49",updated_at:"2017-02-02 11:42:02"},{id:32,name:"Sub Brand 7",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:24:57",updated_at:"2017-02-02 11:42:18"},{id:33,name:"Sub Brand 8",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:25:04",updated_at:"2017-02-02 11:42:34"},{id:34,name:"Sub Brand 9",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:25:39",updated_at:"2017-02-02 11:42:43"},{id:35,name:"Sub Brand 10",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:25:46",updated_at:"2017-02-02 11:42:52"},{id:36,name:"Sub Brand 4",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:43:53",updated_at:"2017-02-02 11:43:53"}]},{id:12,name:"Parent Brand 2",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 09:56:16",updated_at:"2017-02-02 09:56:16",subBrands:[]},{id:16,name:"Brand no children",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 10:37:40",updated_at:"2017-02-02 10:37:40",subBrands:[]},{id:37,name:"Whoops brand",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 11:44:10",updated_at:"2017-02-02 11:44:10",subBrands:[]}];
    
    brands.forEach(function(brand) {
        brand.subBrands = brand.subBrands.filter(function(subBrand){
          return subBrand.id != 31;
      })  
    });
    
    console.log(brands);

    【讨论】:

      【解决方案5】:

      如果您只需要查看数组中每个项目的“subBrands”属性,并且您使用的是下划线,则此方法有效:

      var myBrand = _.each(brands, function(brand) {
        brand.subBrands = _.filter(brand.subBrands, function(subBrand) {
          return subBrand.id != 31;
        });
      });
      

      【讨论】:

        【解决方案6】:

        jQuery 方式

        function removeById(data, id){
        
           $(data).each(function(i, e){
        
              if(e.subBrands.length > 0){
        
                 $(e.subBrands).each(function(_i, _e){
        
                    if(_e.id == id){
        
                      e.subBrands.splice(_i,1);
                      return false;
        
                    }
        
                });
        
             }
        
           });
        
          return data;
        
        }
        
        console.log(removeById(data,32))
        

        此函数将返回您的整个数据数组,不包含特定的 id 对象

        【讨论】:

          【解决方案7】:

          您可以使用for..of 循环来迭代每个subBrands 数组,Array.prototype.splice() 以从数组中删除具有id 31 的对象。

          for (let {subBrands} of data) {
            let n = 0;
            for (let {id} of subBrands) {
              if (id === 31) {
                subBrands.splice(n, 1);
                break;
              }
              ++n;
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2017-03-08
            • 1970-01-01
            • 1970-01-01
            • 2022-10-17
            • 1970-01-01
            • 2020-12-07
            • 2021-12-28
            • 1970-01-01
            • 2019-11-15
            相关资源
            最近更新 更多