Underscore.js - 从嵌套数组中删除项目?

时间:2017-11-29 16:22:20

标签: javascript underscore.js

我有以下对象数组:

var list = [{
  "id": 119,
  "files": []
}, {
  "id": 126,
  "files": [{
    "id": 9,
    "filename": "test1.docx",
  }, {
    "id": 10,
    "filename": "test2.docx",
  }]
}]

如何通过删除具有特定id的文件来更新列表(文件ID是唯一的)例如,我想删除id为10的文件。

这是我到目前为止尝试使用下划线但它不起作用:

_.each(list.item, function(item, idx) {
  if (_.findWhere(item.files, { id: 10 })) {
    //remove file from files array
    files.splice(idx, 1); 
  }
});

我想通过删除具有特定ID

的文件对象来更新列表

到目前为止,所有解决方案都会创建原始副本。有没有办法简单地将它从原始列表中拼接出来?

5 个答案:

答案 0 :(得分:1)

事实上,你可以在没有下划线的情况下完成它:

var list = [{"id": 119, "files": []}, {"id": 126, "files": [{"id": 9, "filename": "test1.docx"}, {"id": 10, "filename": "test2.docx", }]}]

var itemId = 126
var fileId = 10

var out = list.map(function(item) {
    if (item.id === itemId) {
        // Copy the item in order to not mutate the original object
        var itemCopy = Object.assign({}, item)
        itemCopy.files = itemCopy.files.filter(function(file) { return file.id !== fileId })
        return itemCopy
    } else return item
})

console.log(out)
    

答案 1 :(得分:0)

你可以将_without与findWhere结合起来。我猜你要删除那个id的整个数组。

var list = [
               {
                 "id": 119,
                 "files": []
                },
                {
                 "id": 126,
                 "files": [
                     {
                       "id": 9,
                       "filename": "test1.docx",
                     },
                     {
                       "id": 10,
                       "filename": "test2.docx",
                     }
                   ]
                }
             ];
list = _.without(list, _.findWhere(list, {
  id: 119
}));
console.log(list);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

答案 2 :(得分:0)

顺便说一下:您也可以使用新的对象扩展运算符在ES6中执行此操作,并过滤掉不匹配 ID的对象。当然,这会返回一个新对象而不是从现有对象中删除对象,但它可能是您的选择。

const out = list.map(el => {
  return {
    ...el,
    files: el.files.filter(f => f.id !== 9)
  }
});

<强> DEMO

如果没有Babel插件,这在以前是不可能的,但它看起来现在已经在现代浏览器中登陆了。

答案 3 :(得分:0)

你可以用这种方式使用原生javascript:

1)如果我只有文件ID,如何删除文件对象? (文件ID是唯一的)

// ES6 version
const deleteFile1Es6 = (fileId) => {
    for(item of list){
        const file = item.files.filter(file => file.id === fileId)[0];
        if(file != null){
            item.files.splice(item.files.indexOf(file), 1);
            break;
        }
    }
};

// ES5 version
function deleteFile1Es5(fileId) {
    for(var i = 0; i < list.length; i++){
        var item = list[i];
        var fileFoundIndex = -1;
        for(var j = 0; j < item.files.length; j++){
            var file = item.files[j];
            if(file.id === fileId){
                fileFoundIndex = j;
                break;
            }
        }
        if(fileFoundIndex !== -1){
            item.files.splice(fileFoundIndex, 1);
            break;
        }
    }
}

2)如果我同时拥有项目ID和文件ID,那么如何删除文件对象?

const deleteFile2Es6 = (itemId, fileId) => {
    const item = list.filter(item => item.id === itemId)[0];
    if(item != null){
        const file = item.files.filter(file => file.id === fileId)[0];
        if(file != null){
            item.files.splice(item.files.indexOf(file), 1);
        }
    }
};

答案 4 :(得分:0)

您可以使用array#forEach遍历list数组,然后使用array#filter获取所有不具有文件ID的文件并重新分配给文件数组对于每份工作。

&#13;
&#13;
var list = [{ "id": 119, "files": [] }, { "id": 126, "files": [{ "id": 9, "filename": "test1.docx", }, { "id": 10, "filename": "test2.docx", }] }];
var deleteWithFileId = (fileId) => list.forEach((o) => {
  o.files = o.files.filter(({id}) => fileId !== id);
});
deleteWithFileId(10)
console.log(list);
&#13;
&#13;
&#13;

ES 5代码

&#13;
&#13;
var list = [{ "id": 119, "files": [] }, { "id": 126, "files": [{ "id": 9, "filename": "test1.docx" }, { "id": 10, "filename": "test2.docx" }] }];
var deleteWithFileId = function (fileId) {
  return list.forEach(function (o) {
    o.files = o.files.filter(function (obj) {
      return fileId !== obj.id;
    });
  });
};
deleteWithFileId(10);
console.log(list);
&#13;
&#13;
&#13;

要删除文件和项目ID,您可以先对项目ID进行过滤,然后您可以对文件进行过滤。

&#13;
&#13;
var list = [{ "id": 119, "files": [] }, { "id": 126, "files": [{ "id": 9, "filename": "test1.docx", }, { "id": 10, "filename": "test2.docx", }] }];
var deleteWithItemAndFileId = (itemId, fileId) => {
  list.forEach(o => {
    if (o.id === itemId) {
      o.files = o.files.filter(({id}) => id !== fileId);
    }
  })
}

deleteWithItemAndFileId(126, 10)
console.log(list);
&#13;
&#13;
&#13;