数组过滤器不返回预期结果

时间:2017-10-04 08:21:18

标签: javascript typescript

我试图在打字稿中过滤数组我得到了预期的结果,但原始集合被改变了。

private filter(){
            this.data = this.originalData.slice().filter((client: Client) => {
                // Filter list of orders first
                let filteredListOfOrders = client.ListOfOrders.slice().filter((ordersItem: any) => {
                    const searchStr = JSON.stringify(ordersItem).toLowerCase();
                    return searchStr.indexOf(this.filterValue.toLowerCase()) !== -1;
                });

                // Assign filtered list of orders to existing client item 
                client.ListOfOrders = filteredListOfOrders;

                const searchStr = JSON.stringify(client).toLowerCase();
                return searchStr.indexOf(this.filterValue.toLowerCase()) !== -1;
            });
}

export class Client {
   id: number;
   name: string;
   address: string;
   orders: Array<Order>;
}

export class Order {
    id: number;
    dateOfOrder: Date;
    address: string;
}

当我键入地址时,我还要搜索除客户端之外的订单商品,并仅返回具有已过滤地址的客户端以及仅包含已过滤地址的订单。以上工作部分但但由于修改了this.originalData并且仅设置了与过滤器匹配的订单,因此会导致问题。 this.originalData应保持不变。

有谁知道为什么?认为切片返回浅层副本

1 个答案:

答案 0 :(得分:1)

嗯,这不适合评论,所以我将其扩展为答案:

你没有使用&#34;浅&#34;以一种有意义的方式。价值观不浅或深。 副本很浅或很深。

对象的副本(数组只是一个对象)是一个新对象,其属性保存对与原始对象<#>非常相同的对象的引用。 ; s属性。如果修改浅拷贝的某个属性的内容,您将在原始对象的类似属性中看到该修改,因为两个属性都指向非常相同的对象

如果您希望能够在不触及原始内容的情况下修改副本的内容,则需要执行副本,其中您可以逐步查看每个对象的所有属性以及所有属性他们的属性,并制作实际的副本。

并不总是需要完整的深拷贝;通常你只关心修改你的数据结构,你可以将不变的部分保留为浅拷贝。

根据您的具体情况:您正在通过将Client数组替换为包含原始内容的某个子集的新数组来修改orders,并且您不会更改这些内容。所以你真的只需要一个Client对象的浅表副本。您根本不需要slice(),因为您不关心复制数组(并且filter()总是返回一个新数组)。你想做这样的事情:

private filter(){
            this.data = this.originalData.filter((client: Client) => {

                // Filter list of orders first
                let filteredListOfOrders = client.ListOfOrders.filter((ordersItem: any) => {
                    const searchStr = JSON.stringify(ordersItem).toLowerCase();
                    return searchStr.indexOf(this.filterValue.toLowerCase()) !== -1;
                });

                const clientCopy = Object.assign({}, client);
                // Assign filtered list of orders to copied client item 
                clientCopy.ListOfOrders = filteredListOfOrders;

                const searchStr = JSON.stringify(clientCopy).toLowerCase();
                return searchStr.indexOf(this.filterValue.toLowerCase()) !== -1;
            });
}

请注意,我说&#34;类似&#34;这个,因为你的代码没有为我编译(complete and verifiable示例总是有用的)。因此,您必须根据自己的需要调整上述内容。

希望有所帮助;祝你好运!

相关问题