Reputation: 1526
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 useJoin
, 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?).
Upvotes: 0
Views: 129
Reputation: 112447
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. E.g., 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.)
Upvotes: 1