简体   繁体   中英

How to convert Linq-to-objects query with two from clauses to method syntax

How do I convert this LINQ query syntax (this is LINQ to objects) to method syntax:

var occupiedSquares = from s in squares
               from p in pieces
               where Occupies(p, s)
               select s;

( Occupies is a function returning bool . But note that a square does not directly hold a list of occupying pieces, nor does a piece directly hold a list of squares it occupies.).

I thought the answer might use Join , but I can't seem to make it fit the join syntax, because there isn't a common key. (And does the Join method even work on LINQ to objects?).

Two consecutive from -clauses are translated with a SelectMany extension method:

var occupiedSquares = squares
    .SelectMany(s => pieces.Select(p => (s, p))) // Creates a ValueTuple
    .Where(x => Occupies(x.p, x.s))
    .Select(x => x.s);

If you are working with an older Framework version, you can also use an Anonymous Type instead of a ValueTuple .

var occupiedSquares = squares
    .SelectMany(s => pieces.Select(p => new { s, p }))
    .Where(x => Occupies(x.p, x.s))
    .Select(x => x.s);

Alternatively, you can also apply the Where-clause to the nested Select . No aggregate ( ValueTuple or anonymous type) is required in this case:

var occupiedSquares = squares
    .SelectMany(
        s => pieces
            .Where(p => Occupies(p, s))
            .Select(p => s)
    );

The Enumerable.SelectMany Method is typically used to flatten a nested collection. Eg, you have a list of users and the user objects have a list of posts and you need a list of all the posts.

See also my question Nested “from” LINQ query expressed with extension methods and Eric Lippert's answer . (Eric was part of Microsoft's C# compiler team.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM