简体   繁体   中英

Discard rows of a LINQ "from" statement

I'm using the Sprache library, which allows parsers to be built using LINQ. However, sometimes I need to parse something and then discard the result. For example:

from key in Identifier
from __ws1 in OptionalWhitespace
from __setter in PropertySetter
from __ws2 in OptionalWhitespace
from value in PropertyValue
select ...

I don't need any of the three variables prefixed with __ , so it seems unnecessary to pollute the namespace with them.

Is there any way I can perform the LINQ query and discard those three results?

Not having in depth knowledge of Sprache, I've super simplified the example to understand the problem domain.

Take this example of multiple from statements (using LinqPad), where we're only interested in one of the values of the from . So in this arbitrary example, we want to know all the combinations of people and cake, but only interested in the names of the cake.

var people = new List<string> {
    "Billy", "Jimmy"
};

var cake = new List<string> {
    "Carrot Cake", "Chocolate Cake"
};

(from p in people
from c in cake
select new
{
    c
}).Dump();

Multiple from statements can be thought of as nested foreach loops which end up being a cross join (as discussed here LINQ Join with Multiple From Clauses )

So let's assume that this is the intention of the Sprache's authors, if we try to rewrite this in the fluent syntax (as discussed here: https://codeblog.jonskeet.uk/2011/01/28/reimplementing-linq-to-objects-part-41-how-query-expressions-work/ ) it ends up being a SelectMany().

We end up with something like:

people.SelectMany(p => cake, (p, c) => new { c }).Dump();

Which you still end up with the "person" paramater.

So I'd suggest that to keep to Sprache's intent there isn't a way of not having the __ statements. Unless perhaps building up the expression tree yourself, but I can't imagine that would be productive.

In this particular case you can use Then to discard all irrelevant parts at once:

var parser =
    from key in Identifier
    from _ in OptionalWhitespace
        .Then(_ => PropertySetter)
        .Then(_ => OptionalWhitespace)
    from value in PropertyValue
    select new
    {
        key,
        value
    };

But it won't help in the generic case if the irrelevant parts don't immediately follow each other.

Sprache implements LINQ query methods for monadic binding of parser functions like a parser combinator. (LINQ can be used for a lot more interesting stuff than querying EF DbSets.) Sadly discard is not supported for LINQ query range variables (yet) so your '_' range variables will collide in scope. I usually name range variables I don't need like '_N' (where N in [1..]) when I have more than one in a query and hope to remember to use proper discards when they get supported.

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