rx js, как мне сгруппировать объект? - PullRequest
0 голосов
/ 02 апреля 2020

Итак, я видел много онлайн, одна из больших проблем, с которыми я сталкиваюсь, это половина примеров, которые либо не компилируются в машинописи, либо используют устаревшие методы в Rx Js 6.

это то, с чего я начинаю

@registrah([
  { token: 'test', useValue: 1},
  { token: LoggerDefault, useFactory: memoize( createDefaultLogger ) },
  { token: LoggerTypeOrm, useFactory: memoize( createTypeOrmLogger ) },
  { token: LoggerSecurity, useFactory: memoize( createSecurityLogger ) },
])

моя текущая попытка это

  const res = from(registrations).pipe(groupBy(
    (p) => {
      const {token, ...provider } = p;
      return Object.keys(provider)[0];
    }),
    mergeMap(group => group.pipe(
      reduce((acc: Array<AllProvider<any>>, cur) =>[...acc, cur], [])
    ))
  );
  res.subscribe((next) => console.log(next) );

, которая выводит

[ { token: 'test', useValue: 1 } ]
[
  { token: 'defaultLogger', useFactory: [Function: bound variadic] },
  { token: 'typeormLogger', useFactory: [Function: bound variadic] },
  { token: 'securityLogger', useFactory: [Function: bound variadic] }
]

что я хочу - это

{ useValue: [ { token: 'test', useValue: 1 } ] },
{
 useFactory: [
  { token: 'defaultLogger', useFactory: [Function: bound variadic] },
  { token: 'typeormLogger', useFactory: [Function: bound variadic] },
  { token: 'securityLogger', useFactory: [Function: bound variadic] }
]}

, и так как я слишком долго боролся с этим, я также хотел бы увидеть ответ для

{ 
  useValue: [ { token: 'test', useValue: 1 } ],
  useFactory: [
    { token: 'defaultLogger', useFactory: [Function: bound variadic] },
    { token: 'typeormLogger', useFactory: [Function: bound variadic] },
    { token: 'securityLogger', useFactory: [Function: bound variadic] }
  ]
}

1 Ответ

0 голосов
/ 02 апреля 2020

Пожалуйста, смотрите ниже.

В примерах предполагается, что у вас есть все элементы, с которыми вы работаете заранее (т. Е. Выполнено). Если вы этого не сделаете (то есть ответы, поступившие от AJAX), они не будут работать.

Обратите внимание, что для перехода ко второй требуемой форме не нужно использовать groupBy.

const { from } = rxjs;
const { reduce, groupBy, map, mergeMap, toArray } = rxjs.operators;

const registrations = [
  { token: 'test', useValue: 1 },
  { token: 'defaultLogger', useFactory: new Function() },
  { token: 'typeormLogger', useFactory: new Function() },
  { token: 'securityLogger', useFactory: new Function() },
];

// [{ useValue: ... }] | [{ useFactory: ... }, { useFactory: ... }, ...]
from(registrations).pipe(
  map(r => {
    const { token, ...provider } = r;
    const groupKey = Object.keys(provider)[0];
    return { groupKey, value: r };
  }),
  groupBy(r => r.groupKey, r => r.value),
  mergeMap(g => g.pipe(
    reduce((a, r) => {
      if (!a[g.key]) a[g.key] = [];
      a[g.key].push(r);
      return a;
    }, {}),
  )),
).subscribe(console.log);

// { useValue: [ ... ], useFactory: [ ... ] }
from(registrations).pipe(
  reduce((a, r) => {
    const { token, ...provider } = r;
    const key = Object.keys(provider)[0];
    if (!a[key]) a[key] = [];
    a[key].push(r);
    return a;
  }, {})
).subscribe(console.log);
<script src="https://unpkg.com/rxjs@6.5.4/bundles/rxjs.umd.min.js"></script>
...