Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BatchBy : Build up buckets by key. #657

Open
Orace opened this issue Nov 7, 2019 · 1 comment · May be fixed by #659
Open

BatchBy : Build up buckets by key. #657

Orace opened this issue Nov 7, 2019 · 1 comment · May be fixed by #659

Comments

@Orace
Copy link
Contributor

Orace commented Nov 7, 2019

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))
@Orace Orace linked a pull request Nov 7, 2019 that will close this issue
@Orace
Copy link
Contributor Author

Orace commented Nov 11, 2019

Partition functionality are close to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant