Description
Derived from Dispatch
#633 which can surely only be chained with a Zip
, BatchBy
combine Dispatch
and Zip
to builds up buckets that are dictionaries.
IEnumerable<Dictionary<TKey, TValue>> BatchBy<TKey, TValue>(
this IEnumerable<TValue> source,
Func<TValue, TKey> keySelector,
IEnumerable<TKey> acceptedKeys);
An example of use:
Let says that you have the logs of a connection between a client and a server.
All client request start with Q
and all server response start with A
.
There is also some noise that start with #
.
Q> Hy
A> Hello
Q> What's your name ?
#> the fuzz is buzzing
Q> And city ?
A> My name is Bob
Q> And age
#> the buzz is fuzzing
A> I live in Detroit
A> I'm 42
...
That is the input
of type IEnumerable<string>
We want to match each Q
with it's corresponding A
.
We can do it with BatchBy
like this:
var keys = new[] {'Q', 'A'};
var batches = intput.BatchBy(s => s.FirstOrDefault(), keys);
With the example data bellow, batches will yield those dictionaries:
{{Key: 'Q', Value: "Q> Hy"}, {Key: 'A', Value: "A> Hello"}},
{{Key: 'Q', Value: "Q> What's your name ?"}, {Key: 'A', Value: "A> My name is Bob"}},
{{Key: 'Q', Value: "Q> And city ?"}, {Key: 'A', Value: "A> I live in Detroit"}},
{{Key: 'Q', Value: "Q> And age"}, {Key: 'A', Value: "A> I'm 42"}},
...
remark
In the example bellow Q
always come before A
, it may be otherwise, the batches are yield when they have a matching value for each key.
Overload with a static number of keys are possible:
IEnumerable<TResult> BatchBy<TKey, TValue, TResult>(
this IEnumerable<TValue> source,
Func<TValue, TKey> keySelector,
TKey key1,
...,
TKey keyN,
Func<TKey, ..., TKey, TResult> resultSelector);
And can be used like this:
var batches = intput.BatchBy(s => s.FirstOrDefault(), 'Q', 'A', (Question, Answer) => (Question, Answer));
ValueTuple overload are also possibles:
IEnumerable<(TValue, ..., TValue)> BatchBy<TKey, TValue>(
this IEnumerable<TValue> source,
Func<TValue, TKey> keySelector,
TKey key1,
...,
TKey keyN);
To discuss
- Arguments order
- Case of N = 1 (witch is
Where(v => keySelector(v) == v).Select(resultSelector)
)