Как сгруппировать данные JSON по значению с помощью углового ngFor?

#angular #typescript #grouping #ngfor

Вопрос:

У меня есть следующий JSON:

 {
  "data": [
    {
      "workT": "001",
      "workTypeDesc": "Test 1",
      "id": "1",
      "jobNr": "0003",
      "jobDesc": "Header 1",
    },
    {
      "workT": "003",
      "workTypeDesc": "Test 2",
      "id": "2",
      "jobNr": "0002",
      "jobDesc": "Header 2",
    },
    {
      "workT": "001",
      "workTypeDesc": "Test 1",
      "id": "3",
      "jobNr": "0001",
      "jobDesc": "Header 3",
    }
  ],
  "result": null
}
 

Я должен сгруппировать эти данные в соответствии с workT и. workTypeDesc То есть появляться сгруппированными в соответствии с изображением (и демонстрацией):

изображение

Комментарии:

1. Вы можете выполнить итерацию по всем элементам и добавить их в карту, которая содержит список объектов для работы.

2. Пожалуйста, не могли бы вы что-нибудь реализовать, мне не ясно. Thnx

3. Я постараюсь что-нибудь сделать

Ответ №1:

данные могут быть преобразованы несколькими способами, чтобы они подходили в качестве источника для компонента пользовательского интерфейса, который вы хотели бы использовать. Одна из альтернатив состоит в том, чтобы просто сопоставить data массив объекту с одним атрибутом/ключом для каждой группы массивов соответствующего workT значения.

Преобразование данных как таковое не имеет ничего общего с angular, так как это стандартная манипуляция данными Javascript:

 grouped = yourJsonData.data.reduce((group, current)=> {
//create your grouping key, by which you want to group the items
const groupingKey = `${current.workT} - ${current.workTypeDesc}`;
//if the group does not yet have an entry for this key, init it to empty array
group[groupingKey] = group[groupingKey] || [];
//add the current item to the group
group[groupingKey].push(current);
return group;
}, {})
 

Здесь мы берем data массив и используем js reduce для преобразования его в объект, где ключи соответствуют уникальным значениям workT - workTypeDesc , а значение-это массив элементов, которые имеют это workT значение в качестве значения.

Это вы можете затем передать в любую угловую директиву для отображения в виде вложенного элемента, например

 <p-accordion>
    <p-accordionTab header="{{group.key}}" *ngFor="let group of grouped | keyvalue">
        <p-accordion>
            <p-accordionTab header="jobNr:{{item.jobNr}} - jobDesc:{{item.jobDesc}}" *ngFor="let item of group.value">
                <pre>{{item | json }}</pre>
            </p-accordionTab>
        </p-accordion>
    </p-accordionTab>

</p-accordion>
 

Здесь мы используем keyvalue канал из angular, который позволяет выполнять итерацию по ключам объектов(по умолчанию ngFor разрешает только итерацию в качестве источника).

Демонстрация на stackblitz

Ответ №2:

Вот пример того, как вы можете это сделать для разбора :

 // define function that will manage it
var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

let valueToGiveToNgFor = groupBy([
{
  "workT": "001",
  "workTypeDesc": "Test 1",
  "id": "1",
  "jobNr": "0003",
  "jobDesc": "Header 1",
},
{
  "workT": "003",
  "workTypeDesc": "Test 2",
  "id": "2",
  "jobNr": "0002",
  "jobDesc": "Header 2",
},
{
  "workT": "001",
  "workTypeDesc": "Test 1",
  "id": "3",
  "jobNr": "0001",
  "jobDesc": "Header 3",
}], 'workT'); // 'workT' is by you want to groupBy values

  console.log(valueToGiveToNgFor);