简体   繁体   English

Angular5-过滤对象数组

[英]Angular5 - Filtering the array of objects

I am trying to filter view of products but I don't know why original array is being modified, resulting in not correct filtering... 我正在尝试过滤产品视图,但不知道为什么要修改原始数组,导致过滤不正确...

categories is an array with objects of categories {title, products[]} category是一个数组,其中包含类别为{title,products []}的对象

categoriesView I want it to be a filtered array CategoriesView我希望它是一个过滤后的数组

filterByKeyword(keyword: string) {
    let k = keyword.toLowerCase();

    this.categoriesView = this.categories.filter((c) => {
      for(let q = 0; q < c.products.length; q++) {
        return c.products[q].title.toLowerCase().indexOf(k) >= 0;
      }
    });

    // filter products of each category:
    for(let q = 0; q < this.categoriesView.length; q++) {
      for(let z = 0; z < this.categories.length; z++) {
        if(this.categoriesView[q].title == this.categories[z].title){
          this.categoriesView[q].products = this.categories[z].products.filter((p) => {
              return p.title.toLowerCase().indexOf(k) >= 0;
          });
        }
      }
    }

    console.log("Categories View: ", this.categoriesView);
    console.log("Categories: ", this.categories);
}

First filter with categories works correctly. 具有类别的第一个过滤器可以正常工作。 When I dive into products problems appear and original array is modified. 当我深入研究产品时,会出现问题并修改原始阵列。

Sorry but I had to step in. 抱歉,我不得不介入。

Your filtering and code are horrible. 您的过滤和代码太可怕了。

Here it is, rewritten, clearer, simpler, and it might even should work : 在这里,它经过重写,更清晰,更简单,甚至可能可以运行:

filterByKeyword(keyword: string) {

    const k = keyword.toLowerCase();

    this.categoriesView = this.categories.filter(c => {
      let ret = false;
      for(let q of c.products) {
        if(q.title.toLowerCase().includes(k)) { ret = true; }
      }
      return ret;
    });

    // Even cleaner
    // this.categoriesView = this.categories.filter(c => c.products.find(p => p.title.toLowerCase().includes(k)));

    for (const view of this.categoriesView) {
      for (const cat of this.categories) {
        if (view.title === cat.title) {
          view.products = cat.products.filter(p => p.title.toLowerCase().includes(k));
        }
      }
    }

    console.log("Categories View: ", this.categoriesView);
    console.log("Categories: ", this.categories);
}

there is an issue with : 有一个问题:

this.categories.filter( (c) => {...} )

Your array is not iterated properly as it returns at the first round. 您的数组在第一轮返回时未正​​确迭代。 You should concider using a temporary boolean as a buffer for your loop, then return it. 您应该考虑使用临时布尔值作为循环的缓冲区,然后将其返回。

Also, concider refactor your code with Array.prototype.map and Array.prototype.reduce , it will make your code a lot more readable 此外,concider使用Array.prototype.mapArray.prototype.reduce重构代码,这将使您的代码更具可读性

this.categoriesView = this.categories.filter(c => {
    return c.products.reduce( (acc, product) => {
        return acc || product.title.toLowerCase().includes(k);
    }, false);
});

It should work: 它应该工作:

filterByKeyword(keyword: string) {
    const k = keyword.toLowerCase();
    this.categoriesView = this.categories.map(x => Object.assign({}, x));
    this.categoriesView = this.categoriesView.filter((category) => {
        category.products = category.products.filter(
          (product)=> product.title.toLowerCase().includes(k));

        return category.products.length>0 }
      );
    if(this.categoriesView.length===0){
      this.categoriesView = this.categories.map(x => Object.assign({}, x));
    }
  }

In javascript, objects are passed by reference. 在javascript中,对象是通过引用传递的。 So categoriesView actually IS a reference to your categories array and changing the properties in one will change both. 因此, categoriesView实际上是对您的categories数组的引用,更改其中一个的属性将同时更改两者。 If you want to create a separate object, you can use angular.copy() 如果要创建一个单独的对象,可以使用angular.copy()

this.categoriesView = angular.copy(this.categories.filter((c) => {
  for(let q = 0; q < c.products.length; q++) {
    return c.products[q].title.toLowerCase().indexOf(k) >= 0;
  }
}););

see more info here 在这里查看更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM