【问题标题】:How can I remove an element from a list, with lodash?如何使用 lodash 从列表中删除元素?
【发布时间】:2014-02-12 09:56:06
【问题描述】:

我有一个看起来像这样的对象:

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 方法来做到这一点?

【问题讨论】:

  • 您可以使用splice (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) 从列表中删除项目
  • 更改了标题,因为无法以这种方式从数组 [1,4,5] 中删除 4。是的,我确实知道数组可以从哈希/对象中实现,并且可能是,但这两者之间存在细微差别。要从数组中删除,您可以使用 result = _.pull(arr, value) 这将从列表中删除所有匹配的值。

标签: javascript arrays object lodash


【解决方案1】:

最简单最方便的方法-

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

_.without 文档。

【讨论】:

    【解决方案2】:

    您可以使用 removeItemFromArrayByPath 函数,其中包括一些 lodash 函数和拼接

    /**
     * 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

    【讨论】:

      【解决方案3】:

      正如 lyyons 在 cmets 中指出的那样,更惯用和笨拙的方式是使用 _.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});
      

      【讨论】:

      • 这个答案令人震惊的原因是因为您可以使用 谓词函数,这正是我所寻找的。如果您知道索引,则删除元素是微不足道的,但是当您知道索引时呢?
      • 如果你不想改变原始数组,可能值得一提_.filter....
      • @cale_b 谢谢 :-) 用_.filter 版本更新了答案。
      • @thefourtheye _.filter 如果谓词为真,则返回一个元素。您的实现将返回所有不需要的元素,而不是您想要保留的元素
      • @thefourtheye 你应该使用_.reject 而不是_.filter 来使用相同的谓词。查看my answer了解更多详情!
      【解决方案4】:

      除了@thefourtheye 的回答,使用 predicate 而不是传统的匿名函数:

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

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

      【讨论】:

        【解决方案5】:

        据我所知,有四种方法可以做到这一点

        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
        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

          lodash 和打字稿

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

          【讨论】:

            【解决方案8】:

            您现在可以使用_.reject,它允许您根据需要删除的内容而不是需要保留的内容进行过滤。

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

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

            【讨论】:

              【解决方案9】:

              您可以使用_pull 来完成。

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

              查看reference

              【讨论】:

              • 根据文档,_.pull 使用严格相等进行比较,即 ===。两个不同的普通对象永远不会被===(或者==)比较。因此,您上面的代码永远不会从数组中删除任何元素。
              • 然而,这是唯一一个适用于数组中的字符串的方法。 _.remove 只是刷新数组。
              • 我仍然认为这是正确的答案。 JS .filter 删除所有匹配的元素,JS .splice 要求我知道索引, _.remove 迭代数组的所有元素,因此效率较低。 _.pull 正是我想要的:_.pull(array, itemToRemove).
              【解决方案10】:

              只需使用原版 JS。您可以使用splice 删除元素:

              obj.subTopics.splice(1, 1);
              

              Demo

              【讨论】:

              • 用户问Is there an efficient way to use _lodash to delete
              • @Andy 你是对的,但是如果索引还不知道呢?
              • splice() 是最好的方法,如果你想让你的数组发生突变。如果你使用 remove ,那么它会返回新数组,并且必须重新分配。
              • 如果你想通过它在数组中的索引从数组中删除一个项目(显然,如果你想以这种方式执行删除操作,你有这个索引),那么使用 splice 方法是最有效(也是最简单)的方法。无需比较任何东西,使代码更复杂,更容易出现错误和错误......
              猜你喜欢
              • 1970-01-01
              • 2021-03-10
              • 2010-10-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-04-20
              • 1970-01-01
              相关资源
              最近更新 更多