GroupBy divides an Observable into a set of Observables that each emit a different group of items from the original Observable, organized by key.
(length int, distribution func(Item) int, opts ...Option)
| 1303 | |
| 1304 | // GroupBy divides an Observable into a set of Observables that each emit a different group of items from the original Observable, organized by key. |
| 1305 | func (o *ObservableImpl) GroupBy(length int, distribution func(Item) int, opts ...Option) Observable { |
| 1306 | option := parseOptions(opts...) |
| 1307 | ctx := option.buildContext(o.parent) |
| 1308 | |
| 1309 | s := make([]Item, length) |
| 1310 | chs := make([]chan Item, length) |
| 1311 | for i := 0; i < length; i++ { |
| 1312 | ch := option.buildChannel() |
| 1313 | chs[i] = ch |
| 1314 | s[i] = Of(&ObservableImpl{ |
| 1315 | iterable: newChannelIterable(ch), |
| 1316 | }) |
| 1317 | } |
| 1318 | |
| 1319 | go func() { |
| 1320 | observe := o.Observe(opts...) |
| 1321 | defer func() { |
| 1322 | for i := 0; i < length; i++ { |
| 1323 | close(chs[i]) |
| 1324 | } |
| 1325 | }() |
| 1326 | |
| 1327 | for { |
| 1328 | select { |
| 1329 | case <-ctx.Done(): |
| 1330 | return |
| 1331 | case item, ok := <-observe: |
| 1332 | if !ok { |
| 1333 | return |
| 1334 | } |
| 1335 | idx := distribution(item) |
| 1336 | if idx >= length { |
| 1337 | err := Error(IndexOutOfBoundError{error: fmt.Sprintf("index %d, length %d", idx, length)}) |
| 1338 | for i := 0; i < length; i++ { |
| 1339 | err.SendContext(ctx, chs[i]) |
| 1340 | } |
| 1341 | return |
| 1342 | } |
| 1343 | item.SendContext(ctx, chs[idx]) |
| 1344 | } |
| 1345 | } |
| 1346 | }() |
| 1347 | |
| 1348 | return &ObservableImpl{ |
| 1349 | iterable: newSliceIterable(s, opts...), |
| 1350 | } |
| 1351 | } |
| 1352 | |
| 1353 | // GroupedObservable is the observable type emitted by the GroupByDynamic operator. |
| 1354 | type GroupedObservable struct { |
nothing calls this directly
no test coverage detected