perceptr
perceptr

Reputation: 103

How to convert nested loop to a LINQ-statement?

A rather simple question, but I can't work out how to convert a nested loop of such a kind:

for (var a = 0; a < n; a++)
{
    for (var b = a + 1; b < n; b++)
        {
            //let here be a creation of a Tuple
            list.Add(Tuple.Create(a, b))
        }
}

to a LINQ-statement

upd:

I tried something like this:
from a in Enumerable.Range(0, n)
from b in Enumerable.Range(1, n)
...

but it didn't work

Upvotes: 0

Views: 259

Answers (3)

TheyAskedMeToBeUgly
TheyAskedMeToBeUgly

Reputation: 44

Alright, here is one solution using Linq extension methods.

var list = Enumerable.Range(0, n-1)
    .SelectMany(
        a => Enumerable.Repeat(a, n-1 - a)
                .Zip( Enumerable.Range(a+1, n - (a+1)) )
    ).ToList();

How does it work? Well, look up the documentation for the involved Linq methods, that should provide sufficient insight to what's going on here with that ugly Linq construct of mine. (Well, it's not only ugly, it's also so slow you are not at any risk of violating any speed limit...)

Note that the generated list is of type System.Collections.Generic.List<(int First, int Second)>, which is using C# tuples, which are a value types and not to be confused with the System.Tuple type (which is a reference type) you used in the code in your question.


And here is a solution involving Linq query syntax:

var list = (
    from a in Enumerable.Range(0, n - 1)
    from b in Enumerable.Range(a + 1, n - (a + 1))
    select (a, b)
).ToList();

Upvotes: 2

samira mahdavi
samira mahdavi

Reputation: 60

It could be helpfull.

var result = (from a in Enumerable.Range(0, n - 1)
              from b in Enumerable.Range(a + 1, n - a - 1)
              select Tuple.Create(a, b)).ToList();

Upvotes: 2

Behnam
Behnam

Reputation: 347

You may use this: Enumerable.Range(0, n-1).ToList().ForEach(x => Enumerable.Range(x + 1, n-x-1).ToList().ForEach(y => list.Add(Tuple.Create(x,y))));

Upvotes: -1

Related Questions