2

I have a source list of objects of 4 properties with some duplicate values, want to select distinct objects of 2 properties without using a foreach loop.

Source list:

let Students=  [
 {Id: 1, Name: 'A', Class: 'I', Subject: 'Math'},
 {Id: 2, Name: 'B', Class: 'II', Subject: 'Bengali'},
 {Id: 1, Name: 'A', Class: 'I', Subject: 'Science'},
 {Id: 2, Name: 'B', Class: 'II', Subject: 'English'}
];

I want an output list like:

[
  {Id: 1, Name: 'A'},
  {Id: 2, Name: 'B'}
]
1
  • Take a look to this. Commented Jun 22, 2019 at 4:41

6 Answers 6

5

Simple Solution to return Distinct data for Object Array

this.studentOptions = this.students.filter((item, i, arr) => arr.findIndex((t) => t.Id=== item.Id) === i);

Sign up to request clarification or add additional context in comments.

Comments

1

This solution produces the result in the form you asked for. Objects need to be stringified before they get added to the Set, otherwise equal ones are not recognized (see https://stackoverflow.com/a/29759699/2358409).

const set = new Set(Students.map(s => JSON.stringify({ Id: s.Id, Name: s.Name })));
const identifiers = Array.from(set).map(i => JSON.parse(i)); 

If you want to avoid stringify, you can do the following.

const set = new Set(Students.map(s => s.Id + ';' + s.Name));
const identifiers = Array.from(set).map(i => ({ Id: i.split(';')[0], Name: i.split(';')[1] }));

The same can be done in a cleaner way using Map.

const map = new Map();
Students.map(s => map.set(s.Id, { Id: s.Id, Name: s.Name }));
const identifiers = Array.from(map.values());

Comments

1

Since we're in the world of typescript, make use of the types provided by it. Create a class Student, this will be useful for easier management of your objects.

export class Student {
  Id: number;
  Name: string;
  Class?: string;
  Subject?: string;

  constructor(Id: number, Name: string) {
    this.Id = Id;
    this.Name = Name;
  }
}

Create an array to hold the distinct objects:

distinctStud: Student[] = [];

Now you may:

from(this.Students)
   .pipe(
      map(std => new Student(std.Id, std.Name)),
      distinct(x => x.Id && x.Name)
    )
   .subscribe(val => this.distinctStud.push(val));

Comments

0

Array.from(new Set(yourArray.map((item: any) => item.id)))

Comments

0

You can try this like newbie way

    let st=[];
Students.map((data)=>{
 let isExist=!!st.find((data2)=>{ 
 return data2.Id==data.Id});
if(!isExist)
  st.push(data);
});

Comments

0

Using rxjs's map and distinct operators we can achieve this. Please check the code below

   var Students=  [
 {Id: 1, Name: 'A', Class: 'I', Subject: 'Math'},
 {Id: 2, Name: 'B', Class: 'II', Subject: 'Bengali'},
 {Id: 1, Name: 'A', Class: 'I', Subject: 'Science'},
 {Id: 2, Name: 'B', Class: 'II', Subject: 'English'}
];

  const sourceObj = from(Students);
  const mappedObj=sourceObj.pipe(map((x)=>{return {Id: x.Id, Name:x.Name}}));
  const distictObj = mappedObj.pipe(distinct((x)=>x.Id && x.Name));

  console.log(distictObj.subscribe(x=>console.log(x)));

Please check this StackBlitz.

Thanks.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.