Linq operator for an infinite sequence of consecutive halves

Given the seed, imagine an endless sequence of your consecutive halves.

1, 0.5, 0.25, 0.125, ... 

(Ignore any numerical instabilities inherent in double .)

Can this be done in one expression without writing any custom extension methods or generator methods?

+7
source share
5 answers

I don't know one expression, but I found this smart generator code here: http://csharpindepth.com/articles/Chapter11/StreamingAndIterators.aspx

 public static IEnumerable<TSource> Generate<TSource>(TSource start, Func<TSource,TSource> step) { TSource current = start; while (true) { yield return current; current = step(current); } } 

In your case, you will use it:

 foreach (double d in Generate<double>(1, c => c / 2)) { ... } 
+10
source

For fun, here's a trick to creating a real endless sequence in one expression. The first two definitions are class fields, so they do not require initialization of the expression.

 double? helper; IEnumerable<double> infinite; infinite = new object[] { null }.SelectMany(dummy => new double[] { (helper = (helper / 2) ?? 1).Value }.Concat(infinite)); 
+10
source

Here is an answer similar to the one provided by @hvd, but using the Y operator defined here , this eliminates the need for local variables:

 public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f) { return t => f(Y(f))(t); } var halves = Y<double, IEnumerable<double>>(self => d => new[] { 0d }.SelectMany(_ => new[] { d }.Concat(self(d / 2)))); 

Usage example:

 foreach (var half in halves(20)) Console.WriteLine(half); 

What will output 20, 10, 5, 2.5, etc.

I would not recommend using this in production code, but it's fun.

The Y operator also allows other recursive lambda expressions, for example:

 var fibonacci = Y<int, int>(self => n => n > 1 ? self(n - 1) + self(n - 2) : n); var factorial = Y<int, int>(self => n => n > 1 ? n * self(n - 1) : n); var hanoi = Y<int, int>(self => n => n == 1 ? 1 : 2 * self(n - 1) + 1); 
+3
source
 Enumerable.Repeat(1, int.MaxValue).Select((x, i) => x / Math.Pow(2, i)) 

This is not infinite, but since both Repeat and Select use delayed execution, you will not lose any performance.

I don’t know of any own way to create an infinite linq expression.

Or you can manually write an endless version of .Repeat

+2
source

I do not know how to make an infinite sequence with direct LINQ. However, you can make a very long sequence.

 var sequence = Enumerable.Range(0, int.MaxValue) .Select(n => Math.Pow(2, -n)); 

However, since double has finite precision, you will probably only get zeros after n gets too high. You need to experiment to find out what happens and how high n can get before he does it.

0
source

All Articles