我有一个带有某些字段的界面,
interface Item {
id: number;
name: string;
}
我想实现一种方法removeItemsWithName(items: Item[], name: string)
,该方法将从给定数组中删除所有具有给定名称的项:
const myItems: Item[] = [
{ id: 1, name: 'foo' },
{ id: 2, name: 'foo' },
{ id: 3, name: 'bar' }
];
removeItemsWithName(myItems, 'foo');
console.log(myItems);
结果应为:
[{id: 3, name: 'bar'}]
在typescript / javascript中是否有可用的方法array.removeIf()
(例如Java 8中的Collection.removeIf()
),所以我的方法可能类似于以下内容:
function removeItemsWithName(items: Item[], name: string): void {
items.removeIf(i => i.name === name);
}
我已经找到了问题Remove array element based on object property,但是我需要就地修改原始数组,而不是像创建新的数组那样array.filter()
。我还想删除所有符合条件的项目,而不仅仅是第一个。
答案 0 :(得分:3)
标准解决方案为filter
,但这将返回一个 new 数组:
function removeItemsWithName(items: Item[], name: string): Item[] {
return items.filter(i => i.name !== name);
}
但是,如果您确实需要在适当的位置修改数组,则必须使用如下代码:
function removeItemsWithName(items: Item[], name: string): void {
let j = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.name !== name) {
items[j] = item;
j++;
}
}
items.length = j;
}
或使用splice
:
function removeItemsWithName(items: Item[], name: string): void {
for (let i = 0; i < items.length; i++) {
if (items[i].name === name) {
items.splice(i--, 1);
}
}
}
或者您可以使用类似lodash的库,该库具有便捷的remove
方法:
import _remove from 'lodash/remove';
function removeItemsWithName(items: Item[], name: string): void {
_remove(items, x => x.name === name);
}
答案 1 :(得分:1)
您可以使用Array.prototype.filter
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter):
const myItems = [{
id: 1,
name: 'foo'
},
{
id: 2,
name: 'foo'
},
{
id: 3,
name: 'bar'
}
];
console.log(myItems.filter((item) => item.name !== 'foo'))
所以您的功能将仅仅是:
const removeItemsWithName = (items: Item[], name: string): Item[] => items.filter((item: Item) => item.name !== name);
答案 2 :(得分:1)
执行此操作的方法太多,建议使用filter
函数。
尝试一下:
function removeItemsWithName(items: Item[], name: string): void {
items = items.filter(i => i.name !== name);
}
我认为如果removeItemsWithName
函数返回一个新数组并且不更改params值会更好。
function removeItemsWithName(items: Item[], name: string): Item[] {
return items.filter(i => i.name !== name);
}
const myItems: Item[] = [
{ id: 1, name: 'foo' },
{ id: 2, name: 'foo' },
{ id: 3, name: 'bar' }
];
const filtered = removeItemsWithName(myItems, 'foo');
console.log(filtered);
更新
您可以使用Collection
方法创建所有者removeIf
。
interface Item {
id: number;
name: string;
}
class MyCollection<T> {
private items: Array<T>;
constructor(init?: T[]) {
this.items = init || [];
}
get(): T[] {
return this.items;
}
removeIf(conditionFunction: (i: T) => boolean) {
this.items = this.items.filter(i => !conditionFunction(i));
}
}
const myItems: MyCollection<Item> = new MyCollection<Item>([
{ id: 1, name: "foo" },
{ id: 2, name: "foo" },
{ id: 3, name: "bar" }
]);
function removeItemsWithName<T extends Item>(
items: MyCollection<T>,
name: string
): void {
items.removeIf(i => i.name === name);
}
removeItemsWithName(myItems, "foo");
console.log(myItems.get());
答案 3 :(得分:1)
采取一项,利用.filter()
。更少的代码,但是O(2n)。
function removeItemsWithName(items: Item[], name: string): void {
var newArray = items.filter(i => i.name !== name);
items.length = 0; // this empty the original array
newArray.forEach(item => { items.push(item) });
}
取两个,使用旧的O(n)方式.splice()
。
function removeItemsWithName(items: Item[], name: string): void {
var index = items.length - 1;
var predicate = i => i.name === name;
while(index >= 0) {
if (predicate(items[index])) {
items.splice(index, 1)
}
index--;
}
}