gpt4 book ai didi

javascript - 过滤器不是创建一个新数组吗?

转载 作者:行者123 更新时间:2023-11-28 13:05:59 28 4
gpt4 key购买 nike

我对以下代码有疑问,也许我只是不理解过滤器的工作原理。根据我的理解,过滤器应该返回一个新数组。 FilteredItems 是我在 DOM 中执行 *ngFor 的操作。因此,我首先使用 slice 方法将输入项数组浅层复制到 FilteredItems 和 copyItems 中。之后,我尝试从浅复制项目数组中返回一个新的过滤项目数组。但是,每当我尝试过滤项目数组时,它实际上会操作原始数组的数据,而不是仅返回包含我需要的数据的新数组。

@Input() private items: Items[];

private copyItems = new Array<Items>();

public input = new FormControl();
public filteredItems = new Array<Items>();

ngOnInit() {
this.filteredItems = this.items.slice();
this.copyItems = this.items.slice();

this.subscription = this.input.valueChanges
.debounceTime(500)
.distinctUntilChanged()
.map((value) => {
return value;
})
.subscribe((searchTerm) => {
if (searchTerm) {
this.filteredItems = this.filterItems(searchTerm.toLowerCase());
console.log(this.items);
} else {
this.copyItems = this.items.slice();
this.filteredItems = this.items.slice();
}
});
}

private filterItems(searchTerm: string): Array<Items> {
return this.copyItems.filter((item) => {
let filterExists: boolean = false;
let itemName = <string>item.name;
if (itemName.toLowerCase().startsWith(searchTerm)) {
filterExists = true;
}

let filteredChildren = this.filterChildren(searchTerm, item);

if (filteredChildren.length > 0) {
filterExists = true;
item.children = filteredChildren;
}

if (filterExists)
return true;
else
return false;
});
}

private filterChildren(searchTerm: string, item: Items): Array<ChildItems> {
return item.children.filter(child => {
let childName = <string>child.name;
if (childName.toLowerCase().startsWith(searchTerm)) {
return child;
}
});
}

有人可以告诉我我到底做错了什么吗?在过去的两天里,我一直在用头撞 table ,一遍又一遍地解决这个问题,但无法解决。

提前致谢!

最佳答案

filter 确实创建了一个新数组,但原始数组中引用的对象也被新数组引用,因此对它们的更改通过两者都可见。

如果您要更改数组中某个项目的状态,并且不希望通过旧数组看到该更改,则需要创建一个项目并在大批。这将是 map 而不是 filter - 或者更确切地说,就您而言,是两者的组合。

这是您当前正在做的事情的一个更简单的示例;请注意 state 如何变为 2,无论我们在哪个数组中查找它:

var original = [
{id: 1, state: 1},
{id: 2, state: 1},
{id: 3, state: 1}
];
var filtered = original.filter(item => {
if (item.id % 2 == 1) {
++item.state;
return item;
}
});
console.log("original", original);
console.log("filtered", filtered);
.as-console-wrapper {
max-height: 100% !important;
}

坚持现有的Array.prototype函数,你做变异过滤器的方法是使用map然后filter删除未定义条目:

var original = [
{id: 1, state: 1},
{id: 2, state: 1},
{id: 3, state: 1}
];
var filtered = original
.map(item => {
if (item.id % 2 == 1) {
return {id: item.id, state: item.state + 1};
}
})
.filter(item => !!item);
console.log("original", original);
console.log("filtered", filtered);
.as-console-wrapper {
max-height: 100% !important;
}

或者,您可以给自己一个 mapFilter 函数:

Object.defineProperty(Array.prototype, "mapFilter", {
value: function(callback, thisArg) {
var rv = [];
this.forEach(function(value, index, arr) {
var newValue = callback.call(thisArg, value, index, arr);
if (newValue) {
rv.push(newValue);
}
})
return rv;
}
});
var original = [
{id: 1, state: 1},
{id: 2, state: 1},
{id: 3, state: 1}
];
var filtered = original
.mapFilter(item => {
if (item.id % 2 == 1) {
return {id: item.id, state: item.state + 1};
}
});
console.log("original", original);
console.log("filtered", filtered);
.as-console-wrapper {
max-height: 100% !important;
}

...但是有关扩展内置原型(prototype)的所有注意事项都适用(您可以将其作为传递数组的实用程序)。

关于javascript - 过滤器不是创建一个新数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46370223/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com