如何在TypeScript中删除数组项?


Answers:


638

与JavaScript中的方式相同。

delete myArray[key];

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

更好地使用该Array.prototype.splice功能:

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

8
您可以在其中添加类型!var index: number = myArray.indexOf(key, 0);
CorayThan 2015年

17
@CorayThan当然可以将其隐式键入为return indexOfa number吗?
克里斯(Chris

5
@Chris虽然在这种简单情况下很明显,但如果为每个变量明确定义类型,它可以帮助您更快地诊断错误。您已经index在多个位置使用过,并且其中一个(splice)想要查看数字,否则会出现错误。当前,编译器无法阻止您在此处犯错。
Jochem Kuijpers,2016年

33
@blorkfish值得一提的是,如果您有对象列表,则可以使用var index = myArray.findIndex(x => x.prop==key.prop);
弗朗西斯科·卡布拉尔

6
@ Cirelli94-您响应的是旧线程,但问题的答案是删除数组元素不会更改其长度或为数组重新索引。因为阵列是在JavaScript对象,delete myArr[2]字面上删除的属性 2myArr,这是比也不同myArr[2] = undefined。这个故事的寓意只是splice用于此任务,因为这是一种获得预期效果而又不会混淆副作用的安全方法。
winglerw28 '18

199

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

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

19
这不会删除它只是过滤的任何内容。如果列表实际上需要修改,则不是这样。
user573434

5
@ user573434是的,正如名称所示,您是对的。但是,这是要上删除API调用成功等删除对象的情况下,简单的方法
马利克沙赫扎德

3
这对于没有唯一键属性的对象数组非常适合。@ user573434 filter方法返回一个没有过滤对象的新数组,因此结果数组中确实删除了该对象。
杰森

6
我认为为了将其作为对象返回,您必须这样做this.foo_objects = this.foo_objects.filter(obj => obj !== foo_object)[0];
Roel

1
这可行。只需仔细阅读第二行。他使用obj!= foo_object进行过滤。并将其分配给原始变量,从而将原始数组替换为一个减去过滤后的foo_object。与ID对象的数组,用它 deleteById(id: string) { this.data = this.data.filter(d => d.id !== id); }警告的就一个词,如果IDS并不是唯一的,你会删除所有使用相同的id
马库斯

74

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

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

1
无需更改数组引用即可删除的最佳解决方案,并且可以实现特定的相等算法
Sid

1
找到了最佳答案
Gvs Akhil

1
使用ES6的最佳答案
Nathan Beck

2
您还可以使用:this.documents.forEach((item,index,array)=> {if(item === doc)array.splice(index,1);}); 这可能会更清洁,尤其是在使用嵌套数组时。
CGundlach

20

这是我的解决方案:

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();
}

这种解决方案的优点是,即使对象相等无法将两个对象标识为相等,它也将起作用。
Brad Johnson

18

您可以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"]

1
仅供参考,splice方法修改数组(因此在这种情况下删除最后一个项目)并返回删除的项目,而不是数组本身。
CGundlach

2
删除最后一个元素实际上应该是arr.splice(arr.length-1,1)。
Steve In CO


8

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

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

要么

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

1
第一种解决方案的问题是delete删除了元素,但是数组大小与删除之前相同。在第二个解决方案中,我们将有一个新对象,因此,如果我们有spme依赖关系,那么我们将丢失它。接头(在最上面的答案中)没有这种效果。
克里斯汀,

感谢您指出了这一点。我认为在用例中我还没有发现。观察得很好的:)
Jamie Armor

5

使用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;

5

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

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

尽管这确实解决了所提出的问题,但由于创建了新数组并遍历原始数组,因此执行起来很昂贵。一个巨大的数组做这样的操作可能会产生不良的副作用喜欢,更难在移动电池,漫长的等待,JANK等
杰西

1

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

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

0

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

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;
    };
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.