【问题标题】:How to use an object to delete it from objects array javascript?如何使用对象从对象数组javascript中删除它?
【发布时间】:2021-06-13 07:42:08
【问题描述】:

我有一个对象数组,我想检查给定对象是否存在于数组中,如果是,我想删除它,如果没有,我必须将它添加到数组中。

我正在这样做:

 var arr=[
       {
        name: "Jack",
        type: "Jill",
        },
        {
        name: "Heer",
        type: "Ranjha",
        },
       {
        name: "laila",
        type: "Majnu",
        };

]
 
var tosearch = {
        name: "Jack",
        type: "Jill",
        };
if(arr.includes(tosearch))
{
//I want to delete it from the arr.
}
else
   arr.push(tosearch)

如何实现上述实现?

谢谢

【问题讨论】:

    标签: javascript arrays json reactjs object


    【解决方案1】:

    您可以使用此代码

    arr = arr.filter(item => item !== tosearch)
    

    但是,有更好的方法来处理这个问题,您可以为每个对象添加一个 id 字段,并在您想要检查和查找特定项目的任何地方使用该 id

    arr = arr.filter(item => item.id !== tosearch.id)
    

    【讨论】:

    • 这个是正确答案,我已经详细说明了下面的步骤,根据这个核心原理创建实用程序
    【解决方案2】:

    使用过滤器从数组中删除一个元素。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

    const newArray = existingArray.filter(element => element.id != deleteId);
    

    搜索我通常使用一个简单的 findIndex。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

    const doesElementExist = arr.findIndex(element => element.id === selectedId);
    
    if (doesElementExist > 0) { // Delete element }
    

    这取决于您在对象中具有唯一标识符,可能是名称?我不确定你的数据是什么。

    【讨论】:

    • 也存在,为findIndex +1 可能会解决问题的无法解释的用例。
    【解决方案3】:

    问题

    Array.prototype.includes 仅适用于通过浅层引用相等的基元和对象,即如果它们是内存中的同一个对象。

    解决方案

    创建一个实用程序来检查数组是否包含 some 元素,其中“搜索”对象的 每个 属性都相等。

    const arrayContainsObject = (array, object) =>
      array.findIndex((el) =>
        Object.entries(object).every(([key, value]) => el[key] === value)
      );
    

    本示例如果找到则返回元素的索引,否则返回-1

    您可以使用它来过滤数组中的元素或附加它。

    let result;
    const index = arrayContainsObject(arr, toSearch);
    
    if (index !== -1) {
      result = arr.filter((el, i) => i !== index);
    } else {
      result = arr.concat(toSearch);
    }
    

    const arr = [
      {
        name: "Jack",
        type: "Jill"
      },
      {
        name: "Heer",
        type: "Ranjha"
      },
      {
        name: "laila",
        type: "Majnu"
      }
    ];
    
    const toSearch = {
      name: "Jack",
      type: "Jill"
    };
    
    const arrayContainsObject = (array, object) =>
      array.findIndex((el) =>
        Object.entries(object).every(([key, value]) => el[key] === value)
      );
    
    let result;
    const index = arrayContainsObject(arr, toSearch);
    
    if (index !== -1) {
      result = arr.filter((el, i) => i !== index);
    } else {
      result = arr.concat(toSearch);
    }
    
    console.log(result);

    【讨论】:

    • 这似乎是一个很长的过滤方式,为什么不使用过滤器函数的第一个参数来做到这一点?
    • 它的工作,只是想知道它的速度和效率如何
    • @DimitriKopriwa 我不关注你的评论,在 React 中按索引过滤是相当标准的。
    • @rudeTool O(n^2) 查找索引(O(n) 数组外循环,O(n) 元素属性内循环),O(n) 过滤,O(n) 在 concat 上返回一个新的数组。
    • @rudeTool 抱歉,说错了一点,说O(n*m) 会更准确一点,其中n 是迭代的外部数组的元素数,m 是数字要搜索的属性,但 O(n^2) 大致是一般上限。
    【解决方案4】:

    可以使用Array.prototype.filter实现过滤:

    /** utils.js */
    
    
    // default options can be set, here we will create search filter which pick from id
    const defaultSearchFilterOptions = { key: 'id', pick: true }
    
    
    /**
     * @description
     * factory to create array filter utilities
     * @params {object} [options={}] - options used to generate the new filter
     * @params {string} [options.key='id'] - key used for comparing
     * @params {boolean} [options.pick=true] - inverse the filter (with/without)
     * @params {string} options.search - exact match to search (can be improved with a regex or whatever etc..
     * @returns {function} filter - function that can be used with `Array.prototype.filter`
     */
    function createSearchFilter(options = {}) {
      // apply user's options on top of default options, user MUST pass at least "search" options
      const { key, search, pick } = { ...defaultSearchFilterOptions, ...options }
      // return a filter function, based on computed options
      return (item) => pick ? item[key] === search : item[key] !== search
    }
    
    
    /** app.js */
    
    // data
    var arr = [
      {
        name: "Jack",
        type: "Jill",
      },
      {
        name: "Heer",
        type: "Ranjha",
      },
      {
        name: "laila",
        type: "Majnu",
      }
    ];
    
    
    // using factory, create a filter on name where value is "jack"
    const filterInJack = createSearchFilter({ 
      key: 'name',
      search: 'Jack',
    });
    
    // using factory, create a filter on name where value is not "jack"
    const filterOutJack = createSearchFilter({ 
      key: 'name',
      search: 'Jack',
      pick: false,
    });
    
    /** Results */
    
    console.log(arr.filter(filterInJack));
    
    console.log(arr.filter(filterOutJack));

    来源:https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

    【讨论】:

      【解决方案5】:

      如果属性的数量是固定的(在您的情况下是 2 个 nametype)并且您在运行之前就知道它们,那么您可以简单地使用它。

      这种方法可能不是一种理想的方法,但如果数据属于这种类型,那么我想这可能是一种很好且易于理解的方法

      //here i is the index of a object in arr
      if(arr[i].name == tosearch.name && arr[i].type == tosearch.type) {
         //delete it
      } else {
         arr.push(tosearch);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-18
        • 1970-01-01
        • 1970-01-01
        • 2023-01-16
        • 2020-12-07
        • 2016-05-19
        • 2018-08-15
        相关资源
        最近更新 更多