Closed GoogleCodeExporter closed 8 years ago
I like the idea of a Generate method (and I've written one before) but I don't
think
I'd specify either a condition or a number of elements to generate - using Take
and
TakeWhile do that well enough, I think.
I haven't looked at the patch yet - will try to do so tonight.
Original comment by jonathan.skeet
on 16 Feb 2009 at 7:34
We can borrow from Python's (x)range here and add a Range operator:
Range(int stop)
Range(int start, int stop)
Range(int start, int stop, int step)
I can also imagine a default, zero-arguments, overload of Range that produces
the
full series of integers/longs. With this in place, one can use Select and other
existing operators to the same effect. For example:
Series.Expand(2, n => n * n, n > 1000) => (2, 4, 8, 16, 32, 64, 128, 256, 512)
becomes:
Range<int>().Select(n => n + 2)
.Select(n => n * n)
.TakeWhile(n => n < 1000)
That can be a bit mouthful and verbose so I can understand CAmmerman's point to
have
something that simplifies a very common use case. After all, many base LINQ
operators also have overloads for projection (see Max, for example) when there
is
already Select. However, I would stard with Range because that can serve as a
basis
for Expand.
Original comment by azizatif
on 16 Feb 2009 at 9:15
OK, I'm silly and it had momentarily slipped my mind that Range already exists:
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.range.aspx
So we are now talking about:
Range(2, int.MaxValue).Select(n => n * n).TakeWhile(n => n < 1000)
Original comment by azizatif
on 16 Feb 2009 at 9:51
> but I don't think I'd specify either a condition or a number of elements to
generate
I was thinking along the lines of what azizatif was saying, about simplifying
the
common use cases. I'm not married to it however. And we could certainly have
an
overload without the terminator condition or element count. On a related note,
the
terminal check might do better if it worked like TakeWhile, rather than "take
until".
The code itself is older, and I don't remember why I chose to do it this way originally.
There might be a better name for this method than Expand, as well. It was just
the
simplest thing that applied, in my mind at the time.
Original comment by CAmmerman@gmail.com
on 16 Feb 2009 at 1:20
My example (which has since been repeated by Aziz) was not quite right.... The
n * n
should be n * 2, to generate the sequence I specified. n * n would be repeated
squaring, which would overflow quite rapidly. =)
Series.Expand(2, n => n * 2, n > 1000) => (2, 4, 8, 16, 32, 64, 128, 256, 512)
The patch I submitted has the same typo in the comments.
Original comment by CAmmerman@gmail.com
on 16 Feb 2009 at 3:18
If we're looking at Range, I have a much more competent Range class in
MiscUtil. I'm
not sure whether I want to bring that over to MoreLinq though - it's useful
outside
LINQ too, and I'd rather keep to operators.
@Comment 5: That example still isn't right - it should be:
Series.Expand(2, n => n * 2, n => n > 1000)
which I'd still prefer to see as:
Series.Expand(2, n => n * 2).TakeWhile(n => n <= 1000)
Generating a sequence and terminating it are somewhat orthogonal concepts, and
the
latter already exists in a well-known form. I think I'd find the latter easier
to
read, aside from anything else.
Original comment by jonathan.skeet
on 17 Feb 2009 at 6:31
@CAmmerman: You should commit your patch. I agree with Jon, though, to keep the
terminating condition out for now. It can always be added later in version 2.
Meanwhile it does not prevent anyone from having their own overload that
combines
Expand with TakeWhile or Expand with Take to get your original three-part
Expand
version. At least, they'll be getting a tested base to build on.
Original comment by azizatif
on 17 Feb 2009 at 11:32
Implemented in r38.
Original comment by azizatif
on 18 Feb 2009 at 9:31
Original issue reported on code.google.com by
CAmmerman@gmail.com
on 16 Feb 2009 at 2:55Attachments: