Найти уникальный элемент в массиве и найти сумму поля (скажем, меток) для дублированных элементов - PullRequest
0 голосов
/ 14 марта 2019

Этот вопрос может быть похож на В Angular2 * ngFor итерации, как вывести только уникальные значения из массива? , но у меня есть еще некоторые функции.

У меня есть список следующей формы

    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 является динамическим, мы можем добавить столько деталей, сколько необходимо.

Ответы [ 4 ]

2 голосов
/ 14 марта 2019

Если вам нужен результирующий массив имен и меток (сумма дубликатов), то вы можете сделать это более чистым способом в lodash (так как вы пометили lodash). _. GroupBy всегда группирует его по уникальному параметру и группирует все дубликаты с этим параметром внутри массива для каждой группы.

  1. Сначала сгруппируйте его по name, используя _. GroupBy
  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>
0 голосов
/ 14 марта 2019

Вы можете сгруппировать массив учеников по номеру броска и добавить метки с тем же номером броска в накопителе объектов.С помощью 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);
0 голосов
/ 14 марта 2019

Пример, как накапливать ваши значения.

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));
0 голосов
/ 14 марта 2019

Вы можете использовать эту функцию в своей трубе:

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