从列表中选择不同的对象,而无需在角度中使用foreach循环

时间:2019-06-22 04:39:30

标签: angular typescript

我有一个包含4个属性的对象的源列表,这些对象具有一些重复的值,想要选择2个属性的不同对象而不使用foreach循环。

来源列表:

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'}
];

我想要一个输出列表,例如:

[
  {Id: 1, Name: 'A'},
  {Id: 2, Name: 'B'}
]

6 个答案:

答案 0 :(得分:1)

由于我们处在打字稿领域,请使用打字稿提供的 types 。创建一个类Student,这对于简化对象管理很有用。

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

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

创建一个数组来保存不同的对象:

distinctStud: Student[] = [];

现在您可以:

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以像新手一样尝试

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

答案 3 :(得分:0)

使用 rxjs map distinct 运算符,我们可以实现这一目标。请检查下面的代码

   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)));

请检查此StackBlitz

谢谢。

答案 4 :(得分:0)

此解决方案以您要求的形式生成结果。在将对象添加到Set之前,需要先对其进行字符串化,否则将无法识别相等的对象(请参见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)); 

如果要避免使用 stringify ,则可以执行以下操作。

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] }));

可以使用Map以更简洁的方式进行操作。

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

答案 5 :(得分:0)

为对象数组返回不同数据的简单解决方案

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