如何使用lodash从列表中删除一个元素?

201

我有一个长这样的对象:

var obj = {
    "objectiveDetailId": 285,
    "objectiveId": 29,
    "number": 1,
    "text": "x",
    "subTopics": [{
        "subTopicId": 1,
        "number": 1
    }, {
        "subTopicId": 2,
        "number": 32
    }, {
        "subTopicId": 3,
        "number": 22
    }]
}
var stToDelete = 2;

我在我的应用程序中安装了 lodash 以进行其他操作。是否有一种有效的方式可以使用 lodashobj 对象中删除条目:{"subTopicId":2, "number":32}

或者是否有一种 JavaScript 的方法可以做到这一点?


1
你可以使用 splice(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) 从列表中删除项。 - z33m
1
更改了标题,因为不能以这种方式从数组[1,4,5]中删除4。是的,我确实理解数组可以从哈希/对象实现,而且可能是这样,但这两者之间存在微妙的差别。要从数组中删除,您将使用result = _.pull(arr, value)。这将从列表中删除所有匹配的值。 - boatcoder
10个回答

306

正如lyyons在评论中指出的那样,更习惯用lodash的做法是使用_.remove,像这样:

_.remove(obj.subTopics, {
    subTopicId: stToDelete
});
除此之外,您可以传递一个谓词函数,其结果将用于确定当前元素是否需要被移除。
_.remove(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId === stToDelete;
});

或者,您可以使用_.filter过滤旧数组并将其赋值给同一对象来创建一个新数组,就像这样:


obj.subTopics = _.filter(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId !== stToDelete;
});

或者

obj.subTopics = _.filter(obj.subTopics, {subTopicId: stToKeep});

3
这个答案很出色的原因是它提供了一个“谓词函数”的使用方法,这正是我正在寻找的。如果你知道索引,删除元素就很容易,但如果你不知道索引呢? - random_user_name
3
如果您不想改变原始数组,可能值得提及_.filter - random_user_name
@cale_b 谢谢 :-) 已更新答案,加入了 _.filter 版本。 - thefourtheye
7
_.filter 函数会在谓词为真时返回一个元素。您的实现会返回所有不需要的元素,而不是那些您想要保留的元素。 - Xeltor
6
你应该使用_.reject而不是_.filter,以使用相同的谓词。有关详细信息,请查看我的答案 - Xeltor
谓词的想法在我的当前情况下非常好。 - Sean Ch

29

只需使用纯JS。您可以使用splice来删除元素:

obj.subTopics.splice(1, 1);

演示


14
用户询问:“是否有一种有效的方法使用_lodash来删除?” - semirturgay
7
@Andy 你是正确的,但如果索引尚未知道呢? - thefourtheye
4
如果您希望修改数组,则splice()是最好的选择。如果使用remove,则会返回新数组,需要将其重新赋值。 - omarjebari
如果您想通过数组中的索引来删除一个项目(显然,如果您想以这种方式执行删除操作,那么您就有这个索引),那么使用splice方法是最有效(且简单)的方法。无需比较任何内容并使代码变得更加复杂和容易出现错误和漏洞... - TheCuBeMan

28

现在你可以使用_.reject来基于你需要去除的内容进行过滤,而不是基于你需要保留的内容。

与仅适用于数组的_.pull_.remove不同,._reject可用于任何Collection类型。

obj.subTopics = _.reject(obj.subTopics, (o) => {
  return o.number >= 32;
});

除了这个答案之外,原始数组永远不会被改变,并且在设置条件逻辑时更容易阅读你的返回语句。 - klewis

28

你可以使用_pull来完成它。

_.pull(obj["subTopics"] , {"subTopicId":2, "number":32});

请查看参考资料


7
根据文档,_.pull 在比较时使用*严格相等运算符 ===*。两个不同的普通对象将永远不会通过 ===(或者 ==)进行相等比较。因此,您上面的代码将永远不会从数组中删除任何元素。 - Mark Amery
1
然而,这是唯一一个可以处理数组中的字符串的方法。_.remove 只是清空了数组。 - Yauheni Prakopchyk
3
我仍然认为这是正确的答案。JS .filter删除所有匹配的元素,JS .splice需要我知道索引,_.remove遍历数组中的所有元素,因此效率较低。_.pull正是我想要的:_.pull(array, itemToRemove)。 - Judah Gabriel Himango

18

最简单和最方便的方式 -

_.without([2, 1, 2, 3], 1, 2);
// => [3]

_.without 文档。


9

据我所知,有四种方法可以实现这一点。

const array = [{id:1,name:'Jim'},{id:2,name:'Parker'}];
const toDelete = 1;

首先:

_.reject(array, {id:toDelete})

第二个是:
_.remove(array, {id:toDelete})

这样数组将被改变。

第三个是:

_.differenceBy(array,[{id:toDelete}],'id')
// If you can get remove item 
// _.differenceWith(array,[removeItem])

最后一个是:
_.filter(array,({id})=>id!==toDelete)

我正在学习lodash

回答以便于记录,方便日后查找。


我正在寻找 reject - Sampgun

2
除了 @thefourtheye 的回答之外,使用谓词代替传统的匿名函数:
  _.remove(obj.subTopics, (currentObject) => {
        return currentObject.subTopicId === stToDelete;
    });

或者

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});

1

lodash 和 typescript

const clearSubTopics = _.filter(obj.subTopics, topic => (!_.isEqual(topic.subTopicId, 2)));
console.log(clearSubTopics);

0

这是一个简单的lodash函数,使用数组并通过索引号删除它。

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})

0
你可以使用 removeItemFromArrayByPath 函数,它包含一些 lodash 函数和 splice。
/**
 * Remove item from array by given path and index
 *
 * Note: this function mutates array.
 *
 * @param {Object|Array} data (object or array)
 * @param {Array|String} The array path to remove given index
 * @param {Number} index to be removed from given data by path
 *
 * @returns {undefined}
 */

const removeItemFromArrayByPath = (data, arrayPath, indexToRemove) => {
  const array = _.get(data, arrayPath, []);
  if (!_.isEmpty(array)) {
    array.splice(indexToRemove, 1);
  }
};

你可以在这里查看示例: https://codepen.io/fatihturgut/pen/NWbxLNv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接