2017-05-20 3 views
2

개체 목록에서 시작하여 그룹화되고 집계 된 값 배열 (ngFor와 함께 사용할 수 있음)을 얻는 방법을 파악하려고합니다. 나는 그것을 작동하게 만들 수 없다.Angular/ngrx - 상태 값 그룹화 및 집계

[{name: "A", value: 4}, {name: "B", value: 7}] 
:

[{name: "A", value: 1, desc: 'something irrelevant'}, 
{name: "A", value: 3, desc: 'also other properties'}, 
{name: "B", value: 2, desc: 'etc.'}, 
{name: "B", value: 5, desc: 'etc.'}] 

내가 얻기 위해 노력하고있어 결과가 같은 (종류가 다르므로주의)입니다 : (내 상태의 조각입니다) 데이터는 다음과 같이 보입니다

그래서 기본적으로 별명의 "이름"과 해당 이름을 가진 모든 개체의 "값"의 합계를 찾고 ngFor | 비동기.

거의 순간에,이다, 별개의 값을 얻을 수 솔루션을 작업 :

 this.aggregates:Observable<any[]> = this.store 
     .select(state => state.valuesList) 
     .map(valuesList => valuesList.sort((a,b) => {return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0);} })) 
     .flatMap(valuesList => valuesList) 
     .map(value => value.name) 
     .distinct(); 

나는이 시작 드리겠습니다; 문제는 toArray()를 추가하지 않으면 Typescript가 "Type string을 type [] []"에 할당 할 수 없다는 것에 대해 불평합니다. distinct() 뒤에 toArray()를 추가하면 더 이상 불평하지 않지만 subscribe()는 결과를 반환하지 않습니다.

내가 뭘 잘못하고 있니? 나는 감속기로 모든 것을 옮겨야합니까? (그렇다면 같은 감속기에서 다른 동작에 의해 반환되는 객체의 유형을 변경할 수 있는지 모르겠습니다)? 도움이 매우 대단히 감사합니다.

업데이트 : 올바르게 사용 사례가되어야하므로 작업 그룹 By() 구현이 더 행복 할 것입니다. 이 같은

+0

()와 동등? 당신은 당신이 할 수있는 일을 알고 있습니다. – Chrillewoodz

+0

distinct(); 뒤에 toArray()를 끝에 추가합니다. X를 캐스팅 할 때의 문제는 해당 distinct()의 최종 결과가 Observable 이 아닌 Observable 인데, 이는 내가 기대하는 것입니다 ... – pgcd

+0

plunkr을 만들 수 있습니까? – Chrillewoodz

답변

3

당신은 당신이 원하는 것을 할 groupBy를 사용할 수 있지만에서 파생 된 관찰에 groupBy 연산자를 사용해야 목록 - groupBy은 항목의 관찰 가능을 기대합니다. 다음 코드에서

, slice는 어디 toArray을 추가하려면 this.store.select(state => state.valuesList)

const slice = Rx.Observable.of([ 
 
    { name: "A", value: 1, desc: "something irrelevant" }, 
 
    { name: "A", value: 3, desc: "also other properties" }, 
 
    { name: "B", value: 2, desc: "etc." }, 
 
    { name: "B", value: 5, desc: "etc." } 
 
]); 
 

 
const grouped = slice.concatMap(list => Rx.Observable 
 
    .from(list) 
 
    .groupBy(item => item.name) 
 
    .mergeMap(group => group 
 
    .reduce((total, item) => total + item.value, 0) 
 
    .map(total => ({ name: group.key, value: total })) 
 
) 
 
    .toArray() 
 
); 
 

 
grouped.subscribe(value => console.log(value));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

+0

감사합니다! 실제로 다른 속성을 줄여야한다는 사실을 수용하기 위해 몇 가지 사항을 변경해야했습니다. 그러나 이것이 내가 찾고 있었던 것입니다. – pgcd

1

일도 :

import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/from'; 
import 'rxjs/add/operator/map'; 

function main() { 
    const t = [ 
     { name: "C", value: 3, desc: 'also other properties' }, 
     { name: "A", value: 1, desc: 'something irrelevant' }, 
     { name: "B", value: 2, desc: 'etc.' }, 
     { name: "A", value: 3, desc: 'also other properties' }, 
     { name: "B", value: 5, desc: 'etc.' } 
    ]; 

    const store = Observable.from(Array(100).fill(t)); 

    const aggregates: Observable<any[]> = store 
    .map((valuesList) => valuesList 
     .map((x) => ({ name: x.name, value: x.value })) 
     .sort((a, b) => a.name.localeCompare(b.name)) 
     .reduce((pre, cur) => { 
      const len = pre.length - 1; 

      if (pre[len] && pre[len].name === cur.name) { 
       pre[len].value += cur.value; 
       return pre; 
      } 
      pre[len + 1] = cur; 
      return pre; 
     }, []) 
    ); 

    return aggregates; 
} 

main().subscribe((x) => { 
    console.dir(x, { depth: null }); 
}); 

출력은 다음과 같습니다

[ { name: 'A', value: 4 }, 
    { name: 'B', value: 7 }, 
    { name: 'C', value: 3 } ] 
[ { name: 'A', value: 4 }, 
    { name: 'B', value: 7 }, 
    { name: 'C', value: 3 } ] 
[ { name: 'A', value: 4 },....