【问题标题】:如何在 TypeScript 中删除数组项?
【发布时间】:2013-02-23 21:30:26
【问题描述】:

我有一个我在 TypeScript 中创建的数组,它有一个我用作键的属性。如果我有那个密钥,我怎样才能从中删除一个项目?

【问题讨论】:

    标签: arrays typescript collections


    【解决方案1】:

    与在 JavaScript 中的方式相同。

    delete myArray[key];
    

    请注意,这会将元素设置为undefined

    最好使用Array.prototype.splice函数:

    const index = myArray.indexOf(key, 0);
    if (index > -1) {
       myArray.splice(index, 1);
    }
    

    【讨论】:

    • 你可以添加一个类型! var index: number = myArray.indexOf(key, 0);
    • @CorayThan 当然它会被隐式输入,因为indexOf 返回一个number
    • @Chris 虽然在这个简单的案例中很明显,但如果您为每个变量明确定义类型,它可以帮助您更快地诊断错误。您已经在不止一次的地方使用了index,并且其中一个地方 (splice) 想要查看一个数字,否则您会收到错误消息。目前编译器无法防止你在那里犯错。
    • @blorkfish 值得一提的是,如果你有一个对象列表,你可以使用var index = myArray.findIndex(x => x.prop==key.prop);
    • @Cirelli94 - 您正在回复较旧的线程,但您的问题的答案是删除数组元素不会更改其长度或重新索引数组。因为数组是 JavaScript 中的对象,delete myArr[2] 从字面上删除了myArr属性 2,这也与myArr[2] = undefined 不同。这个故事的寓意是只使用splice 来完成这项任务,因为它是一种安全的方法,可以在不混淆副作用的情况下获得所需的效果。
    【解决方案2】:

    如果数组是对象类型,那么最简单的方法是

    let foo_object // Item to remove
    this.foo_objects = this.foo_objects.filter(obj => obj !== foo_object);
    

    【讨论】:

    • 这不会删除它只是过滤的任何内容。如果列表确实需要修改,则不是这样。
    • @user573434 是的,正如名称所示,您是对的。但是,如果您想在成功的 delete api 调用等时删除对象,这是一种简单的方法。
    • 这对我来说非常适用于没有唯一键属性的对象数组。 @user573434 filter 方法返回一个没有过滤对象的新数组,因此结果数组确实删除了对象。
    • 我认为为了将其作为对象返回,您必须这样做this.foo_objects = this.foo_objects.filter(obj => obj !== foo_object)[0];
    • 这不会修改原始数组,它会创建一个新数组
    【解决方案3】:

    在 ES6 中,您可以使用以下代码:

    removeDocument(doc){
       this.documents.forEach( (item, index) => {
         if(item === doc) this.documents.splice(index,1);
       });
    }
    

    【讨论】:

    • 在不更改数组引用的情况下删除的最佳解决方案,并有可能实现特定的相等算法
    • 已找到最佳答案
    • 使用 ES6 的最佳答案
    • 你也可以使用:this.documents.forEach((item, index, array) => { if(item === doc) array.splice(index,1); });这可以更简洁,尤其是在使用嵌套数组时。
    • @MashukurRahman 的问题是关于如何删除一项,而不是多次出现
    【解决方案4】:

    这是我的解决方案:

    onDelete(id: number) {
        this.service.delete(id).then(() => {
            let index = this.documents.findIndex(d => d.id === id); //find index in your array
            this.documents.splice(index, 1);//remove element from array
        });
    
        event.stopPropagation();
    }
    

    【讨论】:

    • 这个解决方案的好处在于,即使对象相等无法将两个对象识别为相等,它也能正常工作。
    【解决方案5】:

    您可以对数组使用splice 方法来删​​除元素。

    例如,如果您有一个名称为 arr 的数组,请使用以下代码:

    arr.splice(2, 1);
    

    所以这里以索引为 2 的元素为起点,参数 2 将确定要删除的元素数量。

    如果要删除名为arr 的数组的最后一个元素,请执行以下操作:

    arr.splice(arr.length-1, 1);
    

    这将返回删除最后一个元素的 arr。

    例子:

    var arr = ["orange", "mango", "banana", "sugar", "tea"];
    arr.splice(arr.length-1, 1)
    console.log(arr); // return ["orange", "mango", "banana", "sugar"]
    

    【讨论】:

    • 仅供参考,splice 方法会修改数组(因此在这种情况下会删除最后一项)并返回已删除的项,而不是数组本身。
    • 其实应该是 arr.splice(arr.length-1,1) 去掉最后一个元素。
    • 为了删除数组的最后一个元素,我会使用数组的pop 方法而不是splice
    【解决方案6】:

    让部门是一个数组。你想从这个数组中删除一个项目。

    departments: string[] = [];
    
     removeDepartment(name: string): void {
        this.departments = this.departments.filter(item => item != name);
      }
    

    【讨论】:

      【解决方案7】:

      这是一个简单的单行代码,用于从对象数组中按属性删除对象。

      delete this.items[this.items.findIndex(item => item.item_id == item_id)];
      

      this.items = this.items.filter(item => item.item_id !== item.item_id);
      

      【讨论】:

      • 第一个解决方案的问题是删除删除了元素,但数组大小保持与删除之前相同。在第二种解决方案中,我们将拥有一个新对象,因此如果我们有 spme 依赖关系,那么我们将失去它。 Splice(在最佳答案中)没有这种效果。
      • 感谢您指出这一点。我认为在我的用例中我还没有发现这一点。观察得很好:)
      【解决方案8】:

      这对我有用。

      你的数组:

      DummyArray: any = [
          { "id": 1, "name": 'A' },
          { "id": 2, "name": 'B' },
          { "id": 3, "name": 'C' },
          { "id": 4, "name": 'D' }
      ]
      

      功能:

      remove() {
          this.DummyArray = this.DummyArray.filter(item => item !== item);
      }
      

      注意:此函数会删除数组中的所有对象。如果要从数组中删除特定对象,请使用此方法:

      remove(id) {
          this.DummyArray = this.DummyArray.filter(item => item.id !== id);
      }
      

      【讨论】:

        【解决方案9】:

        如果您需要从数组中删除给定的对象,并且您希望确保以下几点,请使用此选项:

        • 列表未重新初始化
        • 数组长度已正确更新
            const objWithIdToRemove;
            const objIndex = this.objectsArray.findIndex(obj => obj.id === objWithIdToRemove);
            if (objIndex > -1) {
              this.objectsArray.splice(objIndex, 1);
            }
        

        【讨论】:

        • 您能分享一下为什么您对每个变量都使用 const 吗?
        • @shivamsrivastava 我喜欢代码在可能的情况下是不可变的;因此我使用的是const 而不是let
        【解决方案10】:

        使用 TypeScript 展开运算符 (...) 回答

        // Your key
        const key = 'two';
        
        // Your array
        const arr = [
            'one',
            'two',
            'three'
        ];
        
        // Get either the index or -1
        const index = arr.indexOf(key); // returns 0
        
        
        // Despite a real index, or -1, use spread operator and Array.prototype.slice()    
        const newArray = (index > -1) ? [
            ...arr.slice(0, index),
            ...arr.slice(index + 1)
        ] : arr;
        

        【讨论】:

          【解决方案11】:

          另一个使用 Typescript 的解决方案:

          let updatedArray = [];
          for (let el of this.oldArray) {
              if (el !== elementToRemove) {
                  updated.push(el);
              }
          }
          this.oldArray = updated;
          

          【讨论】:

          • 虽然这确实解决了所提出的问题,但由于创建了一个新数组并在原始数组上循环,因此执行起来很昂贵。在一个巨大的阵列上执行这种操作可能会产生不良的副作用,例如移动电池更难、等待时间长、卡顿等。
          【解决方案12】:
          let a: number[] = [];
          
          a.push(1);
          a.push(2);
          a.push(3);
          
          let index: number = a.findIndex(a => a === 1);
          
          if (index != -1) {
              a.splice(index, 1);
          }
          
          console.log(a);
          

          【讨论】:

            【解决方案13】:

            Typescript/Javascript 中的多个选项可从数组中删除元素。 拼接是最好的选择

            1. 它在不创建新对象的情况下删除内联
            2. 它正确地更新了数组的长度(不会留下空白的空元素)

            以下是使用 Splice 函数根据对象数组中的某些字段删除对象的示例

            const persons = [
             {
               firstName :'John',
               lastName :'Michel'
              },
              {
               firstName :'William',
               lastName :'Scott'
              },  
              {
               firstName :'Amanda',
               lastName :'Tailor'
              }
            ]
            
            console.log('Before Deleting :'+JSON.stringify(persons));
            console.log('Deleting William:');
            persons.splice(persons.findIndex(item => item.firstName === 'William'),1);
            console.log('After Deleting William'+JSON.stringify(persons));

            【讨论】:

            • 我认为你在这里误用了“变异”这个词,因为拼接肯定会变异原始对象
            【解决方案14】:

            只是想为数组添加扩展方法。

            interface Array<T> {
                  remove(element: T): Array<T>;
                }
            
                Array.prototype.remove = function (element) {
                  const index = this.indexOf(element, 0);
                  if (index > -1) {
                    return this.splice(index, 1);
                  }
                  return this;
                };
            

            【讨论】:

              【解决方案15】:

              您可以尝试先获取列表或数组的索引或位置,然后使用 for 循环将当前数组分配给临时列表,过滤掉不需要的项目并将想要的项目存储回原始数组

              removeItem(index) {
                  var tempList = this.uploadFile;
                  this.uploadFile = [];
              
                  for (var j = 0; j < tempList.length; j++) {
                    if (j != index)
                      this.uploadFile.push(tempList[j]);
                  }
                }
              

              【讨论】:

                【解决方案16】:

                我们可以使用filterincludes来实现逻辑

                const checkAlpha2Code = ['BD', 'NZ', 'IN']
                
                let countryAlpha2Code = ['US', 'CA', 'BD', 'NZ', 'AF' , 'AR' , 'BR']
                
                
                /**
                 * Returns the modified array countryAlpha2Code 
                 * after removing elements which matches with the checkAlpha2Code
                 */
                countryAlpha2Code = countryAlpha2Code.filter(alpha2code => {
                    return !checkAlpha2Code.includes(alpha2code);
                });
                console.log(countryAlpha2Code)
                // Output: [ 'US', 'CA', 'AF', 'AR', 'BR' ]
                
                
                // Resetting the values again
                countryAlpha2Code = ['US', 'CA', 'BD', 'NZ', 'AF' , 'AR' , 'BR']
                
                
                /**
                 * Returns the modified array countryAlpha2Code 
                 * which only matches elements with the checkAlpha2Code
                 */
                countryAlpha2Code = countryAlpha2Code.filter(alpha2code => {
                    return checkAlpha2Code.includes(alpha2code);
                });
                
                console.log(countryAlpha2Code)
                // Output: [ 'BD', 'NZ' ]

                【讨论】:

                  【解决方案17】:

                  我看到很多抱怨remove 方法不是内置的。考虑使用 Set 而不是数组 - 它内置了 adddelete 方法。

                  【讨论】:

                    【解决方案18】:

                    类似于Abdus Salam Azad answer,但将数组作为参数传递 来自 //https://love2dev.com/blog/javascript-remove-from-array/

                    function arrayRemove(arr:[], value:any) { 
                        
                        return arr.filter(function(ele){ 
                            return ele != value; 
                        });
                    }
                    

                    【讨论】:

                    • 这不是“删除一个项目”,这是“创建一个没有该项目的新数组”。完全不同的东西。
                    • @Clashsoft,没错,但人们通常更喜欢不可变的调用。如果需要,可以将结果重新分配给同一个变量 myArr=arrayRemove(myArr, elemToRemove)。
                    猜你喜欢
                    • 2021-10-19
                    • 2022-08-05
                    • 2021-04-03
                    • 1970-01-01
                    • 2018-01-14
                    • 2016-09-07
                    • 2013-12-02
                    • 1970-01-01
                    相关资源
                    最近更新 更多