Фильтрация и / или группировка данных в Angular 5+ - PullRequest
0 голосов
/ 28 августа 2018

К сожалению, я не контролирую, как API возвращает данные. Я получаю то, что получаю: /

Мне нужна помощь, чтобы правильно отформатировать мои данные или, возможно, использовать пользовательский канал для правильного отображения. Я пробовал разные вещи (mergeMap, фильтр, группировка по трубе и т. Д.), Но я не могу получить именно то, что хочу. Любая помощь будет оценена.

Пример данных

[
  { "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
  { "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
  { "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"},
  ...
]

Компонент

this.searchService.getData().subscribe(searchResults => {
  this.searchResults = searchResults;
  ....? transform data here or custom pipe in template
});

Желаемый результат (показать имя один раз, а затем все связанные фотографии)

Bob Ross
    Photo1
    Photo2
Fred Rogers
    Photo55
...

Какой самый эффективный способ получить результат, который я ищу? Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Следующий код - мое чистое решение RxJS: P

import { from } from 'rxjs';
import { groupBy, mergeMap, map, toArray, tap } from 'rxjs/operators';

let searchResults = [
  { "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
  { "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
  { "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"}
];

from(this.searchResults).pipe(

  // Select necessary attributes
  map(result => {
    //console.log('Result:', result);
    let fname = result['first'];
    let lname = result['last'];
    let photo = result['photoTitle'];
    let rname = [fname, lname].join(' ');
    return { rname, photo };
  }),

  // group objects by `rname` attribute
  groupBy(result => result['rname']),

  // return each item in group as array
  mergeMap(group => {
    //console.log('Group $1:', group);
    return group.pipe(
      toArray(),
    );
  }),

  // Reduce arrays of objects
  map(group => {
    //console.log('Group $2:', JSON.stringify(group));
    let rname = group[0]['rname'];
    return group.reduce((a, b) => {
      return {
        rname: rname,
        photo: [a.photo, b.photo],
      };
    });
  }),

  // Bypass and verify results
  tap(result => console.log('Result:', result)),

).subscribe();
0 голосов
/ 28 августа 2018

Вы можете использовать функции loadash groupBy и toPairs для группировки данных массива на основе имени и фамилии пользователя, как показано ниже: -

var users = [
  { "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
  { "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
  { "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"}
]

var result = _.groupBy(users, (user)=> user.first + ' ' + user.last);
result = _.toPairs(result);

console.log('Result: ', result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

Вы можете либо отформатировать, либо создать свой собственный канал на основе указанной выше функции.

Вы можете обратиться к следующему stackblitz , чтобы увидеть работающее угловое решение.

...