GroupByWithSumPipe для сортировки списка и суммирования атрибута сгруппированных элементов Angular - PullRequest
2 голосов
/ 10 мая 2019

Я использую канал GroupBy для группировки своих данных по параметру, и он работает очень хорошо, но я бы хотел добавить к этому каналу второй параметр, подобный этому:

<li *ngFor="let object of myArray | groupByWithSum:'color':'price'">
    COLOR:{{object.key}} - SUM_PRICE:{{object.sum}}
</li>

Разрешениесумма всех элементов, сгруппированных по атрибуту объекта, здесь price.

Пример: StackBlitz ЗДЕСЬ

Вот мой список объектов:

var myArray = [
    { name: "Apple",    color: "Green",     price: "5,999" },
    { name: "Banana",   color: "Yellow",    price: "6,999" },
    { name: "Grape",    color: "Green",     price: "12,999" },
    { name: "Melon",    color: "Yellow",    price: "10,999" },
    { name: "Orange",   color: "Orange",    price: "3,999" }
];

Я хочу отсортировать этот список по цвету и получить общую сумму prices по color.

И вот что я хотел бы получить:

[
    {
        key: "Green",
        sum: "18,998‬",
        value: [
            { name: "Apple", color: "Green", price: "5,999" },
            { name: "Grape", color: "Green", price: "12,999" }
        ]
    },
    {
        key: "Yellow",
        sum: "17,998",
        value: [
            { name: "Banana", color: "Yellow", price: "6,999" },
            { name: "Melon",  color: "Yellow", price: "10,999" }
        ]
    },
    {
        key: "Orange",
        sum: "3,999",
        value: [
            { name: "Orange", color: "Orange", price: "3,999" }
        ]
    }
];

Я начал StackBlitz , сортируя список по color, но я не могу сделать сумму.Если кто-нибудь захочет мне помочь.

GroupByWithSumPipe:

export class GroupByWithSumPipe implements PipeTransform {
  transform(collection: object[], property: string, sum: string): object[] {
    // prevents the application from breaking if the array of objects doesn't exist yet
    if(!collection) { return null; }

    const groupedCollection = collection.reduce((previous, current)=> {
      if(!previous[current[property]]) {
          previous[current[property]] = [current];
      } else {
          previous[current[property]].push(current);
      }

      return previous;
    }, {});

    // this will return an array of objects, each object containing a group of objects
    return Object.keys(groupedCollection).map(key => ({ key, value: groupedCollection[key] }));
  }
}

Заранее спасибо.

1 Ответ

2 голосов
/ 10 мая 2019

В выписке по вы можете добавить выписку по сумме:

transform(collection: object[], property: string, sum: string): object[] {
  //...

  return Object.keys(groupedCollection).map(key => ({ 
    key, 
    sum: groupedCollection[key].reduce((a, b) => a + parseInt(b[sum]), 0),
    value: groupedCollection[key]
  }));
}

пример

Вы используете строки для цены, хотя я добавил parseInt, чтобы она работала, но вам лучше просто сделать эти значения в исходных данных

...