2016-09-20 3 views
0

우선 스트림에 익숙하지 않아 일부 일반적인 패턴을 파악할 수 있습니다.어떻게 스트림을 그룹화 한 다음 그룹의 키를 기반으로 그룹을 개별적으로 처리합니까?

많은 라이브러리에서 .groupBy (keySelectorFn)를 사용하여 스트림을 스트림으로 분할 할 수 있습니다. 예를 들어,이 스트림 '는'각 객체의 값에 따라 스트림으로 분리된다 (의사 코드, 특정 라이브러리를 기반으로하지 않음) :

var groups = Stream.of(
    { a: 1, b: 0 }, 
    { a: 1, b: 1 }, 
    { a: 2, b: 2 }, 
    { a: 1, b: 3 } 
) 
.groupBy(get('a')); 

내가에 따라 다른 그룹을 처리 할 말 해당 그룹의 'A'의 값은 :

groups.map(function(group) { 
    if (..?) { 
     // Run the group through some process 
    } 

    return group; 
}); 

I '는'각 그룹의 첫 번째 요소를 사용하지 않고 (그리고 그룹의 첫 번째 요소는 소비되는 경우를의 값을 얻는 방법을 볼 수 없습니다 그룹은 더 이상 손상되지 않습니다).

이것은 나에게 스트림과 관련이있는 공통점이있는 것 같습니다. 잘못된 접근 방식을 취하고 있습니까?

--- 편집 --- 여기

내가에 붙어있어 문제의보다 구체적인 예이다 :

var groups = Stream.of(
    { a: 1, b: 0 }, 
    { a: 1, b: 1 }, 
    { a: 2, b: 0 }, 
    { a: 2, b: 1 }, 
    { a: 2, b: 2 }, 
    { a: 1, b: 2 } 
) 
.groupBy(get('a')); 

첫 1 개체를 선택하는 방법 어디 === 1 , 그리고 처음 두 객체는 ​​=== 2이고 다른 객체는 똑바로 통과합니까?

groups.chain(function(group) { 
    return group.key === 1 ? 
     group.take(1) : 
    group.key === 2 ? 
     group.take(2) : 
     group ; 
}); 

을하지만 group.key가 존재하지 않습니다 (그리고 한 경우에도 그것은 조금 ... 냄새 나는 것 같다)이 나에게 논리적 인 것 같다.

+0

이와 비슷한 것을 찾으세요? : http://jsbin.com/haliqerita/edit?js,console –

답변

0

groupBy는 스트림 스트림을 제공합니다 (스트림의 각 값은 스트림 자체 임). fold를 사용하면 각 그룹 (스트림)을 단일 값 (조건문 사용)으로 처리 할 수 ​​있습니다. flatMap은 모든 결과를 단일 스트림에 저장합니다. 다음은 객체 그룹을 처리하는 간단한 예제입니다. 속성 "a"에 따라 객체를 그룹화하고, 값을 기반으로 한 유형 및 val 특성을 포함하는 단일 객체로 산술 연산을 수행합니다. 이 최종 목적은 단일 스트림으로 평평하게됩니다 http://jsbin.com/haliqerita/edit?js,console

희망하는 데 도움이 : 여기

 
var groupStream = Bacon.fromArray([ 
    { a: 1, b: 0 }, 
    { a: 1, b: 1 }, 
    { a: 2, b: 2 }, 
    { a: 1, b: 3 } 
]); 

// -----[stream of objects where a=1]-------[stream of objects where a=2]----> 
var groups = groupStream.groupBy(function(k){ return k.a; }) 

// v is a stream of a=1 objects or a=2 objects 
groups.flatMap(function(v) { 

//fold(reduce) over the values in v (stream) 
    return v.fold({type:'', val: 0},function(acc,i) { 
    if(i.a == 1) { 
     return {type: 'one', val: acc.val + i.b }; 
    } 

    if(i.a == 2) { 
     return {type: 'two', val: acc.val + i.b }; 
    } 
    }) 
}).onValue(function(v) { 
    console.log(v); 
}); 

는 jsbin입니다.

+0

좋아요. .fold() (또는 .reduce())를 사용하는 것이 아마 앞으로 나아갈 수 있음을 알 수 있습니다. 그러나 당신은 'a'내부의 속성 'a'에 대한 조건부 검사를 이미 가지고 있습니다. groupStream을 이미 'a'의 값으로 그룹화 했으므로 그 그룹에 속한 각 객체의 값을 확인해야하는 것이 약간 낭비되는 것 같습니다. 'a'의 스트림에 대해 사람들이 나팔을 부는 것 중 하나는 효율성입니다. 허락하신다면, 하나의 작은 수표는 큰 관심사가 아니지만, 나는 이런 종류의 일에 놀랐습니다. – stephband

+0

이제 첫 번째 1 개 개체를 === 1로 가져 가고 싶지만 처음 몇 개 개체는 === 2. .fold()가 도움이되지 않는다는 것을 상상해보십시오. flatMap - 사실, 'a'의 각 값에 대해 카운터 var가 필요합니다 (그리고 'a'가 얼마나 많은 값인지는 알 수 없습니다). 이상적으로 내가하고 싶다면 if (v.key === 1) {return v.take (1); } if (v.key === 2) {return v.take (2); } ...하지만 v.key와 같은 것은 없습니다 ... – stephband

+0

문제를 설명하기 위해 질문에 예제를 추가했습니다. – stephband