Generate number sequence with step size in linq

The name of the picture


Generate number sequence with step size in linq



I need to generate a sequence of numbers using C# linq. Here is how I have done it using for loop.


int startingValue = 1;
int endValue = 13;
int increment = 5;
for (int i = startingValue; i <= endValue; i += increment) {
Console.WriteLine(i);
}





check this article on generating sequence numbers in LINQ
– Karthik Chintala
6 hours ago





Replace Console.WriteLine(i) with yield return i and wrap it in a method that returns an IEnumerable<int> and you're done. Iterator methods are nice like that.
– Jeroen Mostert
6 hours ago


Console.WriteLine(i)


yield return i


IEnumerable<int>





Where does this 'need' come from? homework requirements? Otherwise, it's probably better to stick to your approach.
– vc 74
6 hours ago






4 Answers
4



If you want to mimic your procedural code, you can use TakeWhile:


Enumerable.Range(0, int.MaxValue).
Select(i => startValue + (i * increment)).
TakeWhile(i => i <= endValue);



But this is to my opinion worse in terms of performance and readability.





@Ofir Winegarten, thanks
– vc 74
6 hours ago



Not everthing has to be done in LINQ to be usasable like Linq, you can stick very close to your original:


IEnumerable<int> CustomSequence(int startingValue = 1, int endValue = 13, int increment = 5)
{
for (int i = startingValue; i <= endValue; i += increment)
{
yield return i;
}
}



Call it like


var numbers = CustomSequence();



or do any further LINQ on it:


var firstTenEvenNumbers = CustomSequence().Where(n => n % 2 == 0).Take(1).ToList();



Try Enumerable.Range in order to emulate for loop:


for


int startingValue = 1;
int endValue = 13;
int increment = 5;

var result = Enumerable
.Range(0, (endValue - startingValue) / increment + 1)
.Select(i => startingValue + increment * i);

Console.Write(string.Join(", ", result));



Outcome:


1, 6, 11



Seems wasteful but the best I can think of is something like this:


int startingValue = 1;
int endValue = 13;
int increment = 5;
var sequence = Enumerable.Range(startingValue,(endingValue-startingValue)+1)
.Where(i=>i%increment == startingValue%increment);



Which is hopefully easy to follow. Logically, all of the values produced by your for loop are congruent to the startingValue modulo increment. So we just generate all of the numbers between startingValue and endingValue (inclusive) and then filter them based on that observation.


for


startingValue


increment


startingValue


endingValue





@mjwills - true, fixed
– Damien_The_Unbeliever
6 hours ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Stripe::AuthenticationError No API key provided. Set your API key using “Stripe.api_key = ”

CRM reporting Extension - SSRS instance is blank

Keycloak server returning user_not_found error when user is already imported with LDAP