Rx: EnumerableEx.For () vs Enumerable.SelectMany ()

System.Interactive.dll includes the For() method with the following implementation:

 IEnumerable<TResult> For<TSource, TResult>( IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> resultSelector) { return source.Select<TSource, IEnumerable<TResult>>(resultSelector).Concat<TResult>(); } 

Am I missing something or is equivalent to the existing Enumerable.SelectMany() , minus this ?

 IEnumerable<TResult> SelectMany<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector) 
+7
c # linq system.reactive system.interactive
source share
3 answers
Good question. They give the same results, but the internal implementations are completely different.

EnumerableEx.For would be added to System.Interactive to maintain the duality between IObservable and IEnumerables. Note: Observable.For and Observable.SelectMany are different:

 IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector) 

against.

 IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector) 

Therefore, you expect EnumerableEx.For to have this signature, and not the one that actually has:

 IEnumerable<TResult> For<TSource, TResult>(**IObservable**<TSource> source, Func<TSource, IEnumerable<TResult>> resultSelector) 

However, obviously, it does not use the IObservable source. Perhaps it was intended. I would ask your question on the Rx forums to find out if the Rx team has an answer.

+1
source share

They look like equivalent functions to me. SelectMany is an extension method in IEnumerable and .For is written as a static method in EnumerableEx, so they are called differently.

  foreach(var s in list.SelectMany(Filter)) { // ... } foreach (var s in EnumerableEx.For(list, Filter)) { // ... } 

I am sure that there are specific reasons for using each of them.

0
source share

I assume that SelectMany goes through everything dynamically, while Concat (in For) traverses all its external IEnumerable elements before starting to register and iterate over them.

In other words, Concat works with a fixed set of IEnumerable, even if it accepts them as IEnumerable. Therefore, in For, the entire IEnumerable set is created before the first TResult is returned. In SelectMany, you immediately get TResult.

0
source share

All Articles