【问题标题】:Find unique element in an array and the find the sum of field(say Marks) for the duplicate elements在数组中查找唯一元素并查找重复元素的字段总和(例如标记)
【发布时间】:2019-08-04 22:33:29
【问题描述】:

这个问题可能类似于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 是动态的,我们可以根据需要添加任意数量的详细信息。

【问题讨论】:

    标签: javascript arrays typescript angular5 lodash


    【解决方案1】:

    如果您需要名称和标记的结果数组(重复项的总和),那么您可以在 lodash 中使用一种非常简洁的方式来完成此操作(因为您标记了 lodash)。 _.groupBy 将始终按其唯一参数对其进行分组,并将所有具有该参数的重复项分组到每个组的数组中。

    1. 首先,使用_.groupBy 将其按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);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 感谢出色的解决方案。
    【解决方案2】:

    你可以在你的管道中使用这个函数:

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

    【讨论】:

    • 感谢您的回答。如果 studentList 是动态的,那么这会起作用吗?
    • 此代码具有破坏性,因为它会改变输入列表中的项目。这不适用于有角度的管道。所以最好在你加载和存储数据的地方使用它。
    • 表示不用写管道?
    • @AnandRaj “意味着不需要写管道?” 这意味着,当您在控制器中加载数据后立即执行此操作,并将数组存储为累积值,那么在渲染数据时就不需要管道来执行此操作。
    【解决方案3】:

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

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

    【讨论】:

    • 这三个点代表什么?意味着...?
    • @AnandRaj 它是一个扩展运算符。在这种情况下,{ ...student } 创建了student 的浅表副本,这样当我执行byName[student.name].mark += student.mark 时就不会从输入数组中改变学生。
    【解决方案4】:

    您可以根据卷号对学生数组进行分组,并在对象累加器中添加相同卷号的标记。使用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);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      相关资源
      最近更新 更多