代码之家  ›  专栏  ›  技术社区  ›  Arj 1411

查找数组中的唯一元素,然后查找重复元素的字段(比如标记)之和

  •  0
  • Arj 1411  · 技术社区  · 7 年前

    这个问题可能类似于 In Angular2 *ngFor iteration, how do I output only unique values from the array? 但我的问题是,它还有一些特点。

    我有以下表格的清单

        let studentsList = [{
            name:'A',
            rollNo:1,
            mark:10
        },
        {
            name:'B',
            rollNo:2,
            mark:30
        },
        {
            name:'C',
            rollNo:3,
            mark:40
        },
        {
            name:'A',
            rollNo:1,
            mark:50
        }
      ]
    

    其目的是显示来自网络的唯一名称和标记 studentList 然后像这样从中找到唯一的名字。

    A   10
    B   30
    C   40
    

    如果名称重复,则添加标记并显示。

    A   60
    B   30
    C   40
    

    我可以像这样过滤唯一的名字

    import { Pipe, PipeTransform } from '@angular/core';
    import * as _ from 'lodash'; 
    
    @Pipe({
      name: 'unique',
      pure: false
    })
    
        export class UniquePipe implements PipeTransform {
            transform(value: any): any{
                if(value!== undefined && value!== null){
                    return _.uniqBy(value, 'name');
                }
                return value;
            }
        }
    

    然后在html中

    <ul>
      <li *ngFor="let student of studentList| unique">
        {{student .name}}
      </li>
    </ul>
    

    编辑

    这个 studentsList 是动态的,我们可以根据需要添加更多细节。

    0 回复  |  直到 7 年前
        1
  •  2
  •   Koushik Chatterjee    7 年前

    如果您需要一个名称和标记的结果数组(重复项的总和),那么您可以在lodash中使用一种非常干净的方法来实现这一点(因为您标记了lodash)。 _.groupBy 将始终按其唯一的参数对其进行分组,并在每个组的数组中使用该参数对所有重复项进行分组。

    1. 首先,将其分组 name 使用 _.群比
    2. 然后地图( .map )每一组,计算分数之和 .sumBy

    以下是一个有效的例子:

    let input = [{"name":"A","rollNo":1,"mark":10},{"name":"B","rollNo":2,"mark":30},{"name":"C","rollNo":3,"mark":40},{"name":"A","rollNo":1,"mark":50}],
        res = _(input)
                .groupBy('name')
                .map((g, name) => ({name, mark: _.sumBy(g, 'mark')}))
                .value();
                
    console.log(res);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
        2
  •  0
  •   guijob    7 年前

    您可以在管道中使用此功能:

    value.reduce((acc, ele) => {
      const existingStudent = acc.find(x => x.name === ele.name);
      if(!existingStudent) return acc.concat(ele);
      return (existingStudent.mark += ele.mark, acc);
    },[])
    

    测试它:

    var studentsList=[{name:"A",rollNo:1,mark:10},{name:"B",rollNo:2,mark:30},{name:"C",rollNo:3,mark:40},{name:"A",rollNo:1,mark:50}];
    
    const resp = studentsList.reduce((acc, ele) => {
      const existingStudent = acc.find(x => x.name === ele.name);
      if(!existingStudent) return acc.concat(ele);
      return (existingStudent.mark += ele.mark, acc);
    },[])
    
    console.log(resp);
        3
  •  0
  •   Thomas    7 年前

    一个如何积累价值的例子。

    let studentsList = [
      { name: 'A', rollNo: 1, mark: 10 },
      { name: 'B', rollNo: 2, mark: 30 },
      { name: 'C', rollNo: 3, mark: 40 },
      { name: 'A', rollNo: 1, mark: 50 }
    ];
    
    const byName = {};
    for (var student of studentsList) {
      if (student.name in byName) {
        byName[student.name].mark += student.mark;
      } else {
        byName[student.name] = { ...student };
      }
    }
    console.log(Object.values(byName));
        4
  •  0
  •   Hassan Imam Ravi kant    7 年前

    您可以根据卷号将学生数组分组,并在对象累加器中添加相同卷号的标记。使用 array#values() 获取与卷号对应的所有值。

    let studentsList = [{ name:'A', rollNo:1, mark:10 }, { name:'B', rollNo:2, mark:30 }, { name:'C', rollNo:3, mark:40 }, { name:'A', rollNo:1, mark:50 } ],
        uniqueStudents = Object.values(studentsList.reduce((r,{name, rollNo, mark}) => {
          r[rollNo] = r[rollNo] || {name, rollNo, total : 0};
          r[rollNo].total += mark;
          return r;
        },{}));
    console.log(uniqueStudents);