简体   繁体   中英

How to display one item per `type` attribute in a list?

I am writing an Angular 8 application. In one of the views there is the option to display a list of items of class Product and this list may be filtered in several ways.

export class Product {
  constructor(
    public id: number,
    public type: number
  ) {
  }
}

What I want to do:

Among the attributes of Product there is type . How can I filter them in order to obtain exactly one item per type? What I would do is use this function, but I don't know how to write the logical statement in parentheses.

filterItemsOnePerType() {
    this.filteredProducts = Object.assign([], this.products).filter(
      item => (... item.type ...)
    );
  }

Notice that it's not really important the item that is going to be selected. What is important is that in the final view I won't see any duplicate among types.

EXAMPLE

I have a list of products:

[{id: 1, type:1},
 {id: 2, type:1},
 {id: 3, type:1},
 {id: 4, type:2},
 {id: 5, type:2},
 {id: 6, type:3},
 {id: 7, type:2}]

What I want to obtain is therefore the following list:

[{id: 1, type:1},
 {id: 4, type:2},
 {id: 6, type:3}]
 this.filteredProducts = Object.assign([], this.products).filter(
   (types => item =>  !types.has(item.type) && types.add(item.type))(new Set)
 );

You might want to use a Set to exclude duplicates.

You could use the Array.reduce method to filter it out.

 const array = [ { id: 1, type: 1 }, { id: 2, type: 1 }, { id: 3, type: 1 }, { id: 4, type: 2 }, { id: 5, type: 2 }, { id: 6, type: 3 }, { id: 7, type: 2 } ]; const result = array.reduce((result, item) => { const isFound = result.find(({ type }) => item.type === type); if (isFound) { return result; } return [...result, item]; }, []); console.log(result);

Going back to your original code, you'd do something like the following:

filterItemsOnePerType() {
  this.filteredProducs = Object.assign([], this.producs).reduce(
    (result, item) => {
      const isFound = result.find(
        ({ type }) => item.type === type
      )
      if (isFound) return result

      return [...result, item]
    }, []
  )
}

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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