Filter unique elements from array using Pipe filter in Angular

11,806

Solution 1

Assuming your article[] is like so:

articles = [
    {
        ArticleTitle: 'article one',
        ArticleTags: [
            {key:0, value:'Back'},
            {key:1, value:'Shoulder'},
            {key:2, value:'Injury'},
            {key:3, value:'Abs'}]
    },
    {
        ArticleTitle: 'article two',
        ArticleTags: [
            {key:3, value:'Abs'},
            {key:1, value:'Shoulder'},
            {key:4, value:'Leg'},
            {key:5, value:'Others'}]}
]


import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
    name: 'filterUnique',
    pure: false
})
export class FilterPipe implements PipeTransform {
    transform(value: any, args?: any): any {
        // Remove the duplicate elements
        var art = value.map(x=>{
            return x.ArticleTags.map(y=>{ return y.value;});;
        }).reduce((acc,ele,i)=>{
            acc = acc.concat(ele);
            return acc;
        });
        return new Set(art);
    }
}

above pipe returns a set of string containing the value of articletag.

<ul>
    <li *ngFor="let a of articles | filterUnique">{{a}}</li>
</ul>

Solution 2

Refere this there unique filter is given https://www.npmjs.com/package/ng2-pipes

  ex:   array | unique: 'Property (Optional)'
        this.items = [1, 2, 3, 1, 2, 3];
        <li *ngFor="let item of items | unique"> <!-- Array: [1, 2, 3] -->
Share:
11,806
Nancy
Author by

Nancy

Updated on July 29, 2022

Comments

  • Nancy
    Nancy almost 2 years

    enter image description hereI am trying to implement pipes using Angular. Below is the code I have tried. I want to retrieve unique for the complete list . So i have added a pipe filter name for the inner list . But i am still getting the duplicate elements. I have added the json for reference .The inner ArticleTags array has a list of objects. Similarly I have multiple ArticleTags array for every parent Array. I want to retrieve the unique elements from the entire list ArticleTags array. I think its retrieving the unique elements within the particular inner list and not retrieving from the entire list of Article Tags.

    enter image description here

    import { Pipe, PipeTransform } from '@angular/core';
    @Pipe({
        name: 'filterUnique',
        pure: false
      })
      export class FilterPipe implements PipeTransform {
        transform(value: any, args?: any): any {
          // Remove the duplicate elements
          const uniqueArray = value.filter(function (el, index, array) {
            return array.indexOf (el) === index;
          });
          return uniqueArray;
        }
      }
    
    
    
    
    
    
    
    <ul>
              <li *ngFor="let articlesResult of articlesListArray; let i=index">
                <ul>
                  <li  *ngFor="let articlesTagResult of articlesResult.ArticleTags | filterUnique; let j=index">
                    <i class="fa fa-times-circle" *ngIf="articlesResult.ArticleTags[j].value"></i>
                    <label class="form-check-label" for="exampleCheck" *ngIf="articlesResult.ArticleTags[j].value">{{articlesResult.ArticleTags[j].value}}</label>
                  </li>
                </ul>
              </li>
            </ul>
    
    
    getLatestArticles(currdate): void {
        this.ng4LoadingSpinnerService.show();
        this.ArticlesServiceCall.getArticlesDashboard(currdate)
          .subscribe(
            resultArray => {
              this.ng4LoadingSpinnerService.hide();
              this.articlesList = resultArray;
              this.articlesLists = resultArray.ResponseValue;
              this.articlesListArray = this.articlesLists.slice(0, 8);
            },
            error => console.log('Error :: ' + error)
          );
      }
    

    I am getting the main array data from articlesListArray and passing that in html


    Edit update on July 09 2018

    Getting the below error with the below pipe code.

    import { Pipe, PipeTransform } from '@angular/core';

    @Pipe({ name: 'filterduplicates' }) export class FilterduplicatesPipe implements PipeTransform {

    transform(value: any, args?: any): any {
        // Remove the duplicate elements
        const art = value.map( x => {
            return x.ArticleTags ? x.ArticleTags.map(y => {
                return y.value ? y.value : null;
            }) : [];
        }).reduce((acc, ele, i) => {
            acc = acc.concat(ele);
            return acc;
        }).filter( z => {
            if (z) {
                return z;
            }
        });
        return new Set(art);
    }
    

    } enter image description here

    • j4rey
      j4rey about 6 years
      so you are looping through articlesListArray to get articlesResult, then in second <li> tag you are looping through articlesResult.ArticleTags to get unique articlesTagResult, but instead of using articlesTagResult.value, you are using articlesResult.ArticleTags[j].value?
    • Nancy
      Nancy about 6 years
      Okay so i tried to use <label class="form-check-label" for="exampleCheck">{{articlesTagResult.value}}</label> but still it retrieves the duplicate elements . I have also attached the screen shot of output for your reference . The second array is a list of elements. Back, Injury ,Lifestyle , Shoulder comes under one list. As per my assumption , it is retrieving the unique elements with in that array. But it doesnt compare with other list of array elements, or I am not sure .
    • j4rey
      j4rey about 6 years
      okay i get it now, you have list of articles, every articles has tags, and you want the union of tags of all articles....right?
    • Nancy
      Nancy about 6 years
      Yes you are exactly right
    • Nancy
      Nancy about 6 years
      @ j4rey89 Any clue on this how to achieve from .ts file . I have pasted .ts code for reference.
    • Nancy
      Nancy almost 6 years
      @j4rey89 stackoverflow.com/questions/50897124/… Can you take a look at this question .
  • Soumya B. Athani
    Soumya B. Athani about 6 years
    ok, then try to use sets in angular to your response from server it will display only unique elements
  • Nancy
    Nancy about 6 years
    I have already done all those. My requirement is well understood by j4rey89 as he had mentioned in his comment.
  • Sanoj_V
    Sanoj_V about 6 years
    can you try to inject in your component @Component({ pipes: [FilterPipe] }) try this also.
  • Nancy
    Nancy about 6 years
    I used the code in pipe file and getting error Cannot read property 'map' of undefined . Could you please remove the repetitive code from your answer and have a single answer . I see there are lots of repetitions. However, I get the above error with the code that you had mentioned in pipe file.
  • j4rey
    j4rey about 6 years
    removed the repetitive code.....As for Cannot read property 'map' of undefined, map is a property of Array make sure the data is of type Array.
  • Nancy
    Nancy about 6 years
    Actually I am getting the list of unique elements displayed :) , but with the error message Cannot read property 'map' of undefined, map is a property of Array in console :( But still I am accepting your answer.
  • j4rey
    j4rey about 6 years
    kindly check the green tick, if my answer helped solved your problem.
  • Nancy
    Nancy about 6 years
    I have done. .But do you know why i am getting that error although I am getting the correct unique list?
  • j4rey
    j4rey about 6 years
    could you provide the complete json data that you are setting in articlesListArray?
  • Nancy
    Nancy about 6 years
    Have another query . I have this cross icon as shown in the above image for every article tag. When i click on the icon , that particular tag should be removed from the list . How to achieve this after retrieving the unique list of elements ? I tried to use splice but deletion of that particular alone is not happening. For me it deleted that specific list completely.
  • j4rey
    j4rey about 6 years
    @Nancy I am afraid you will have to create another question for that since it's a different issue.
  • Nancy
    Nancy almost 6 years
    I am getting map error with the code mentioned above. I have updated the question with error message screen shot and the pipe code. Could you pls help
  • j4rey
    j4rey almost 6 years
    check if articles has values and is of type array using Array.isArray(obj).