开发者

How to perform this query in LINQ?

Consider this brief snippet:

var candidateWords = GetScrabblePossibilities(letters);
var possibleWords = new List<String>();

foreach (var word in candidateWords)
{
    if (word.Length == pattern.Length)
    {
        bool goodMatch = true;
        for (int i=0; i < pattern.Length && goodMatch; i++)
        {
            var c = pattern[i];
            if (c!='_' && word[i]!=c)
                goodMatch = false;
        }
        if (goodMatch)
            possibleWords.Add(word);
    }
}

Is there a way to express this cleanly usin开发者_StackOverflowg LINQ?

What is it?


A straightforward translation would be to overlay each candidate-word over the pattern-word using the Zip operator.

var possibleWords = from word in candidateWords
                    where word.Length == pattern.Length
                       && word.Zip(pattern, (wc, pc) => pc == '_' || wc == pc)
                              .All(match => match)
                    select word;

If you really want to focus on the indices, you can use the Range operator:

var possibleWords = from word in candidateWords
                    where word.Length == pattern.Length
                       && Enumerable.Range(0, word.Length)
                                    .All(i => pattern[i] == '_' 
                                           || pattern[i] == word[i])
                    select word;

EDIT:

As David Neale points out, the Zip operator is not available before .NET 4.0. It's trivial to implement it yourself, however.


Another way of doing this w/o Zip:

var possibleWords = candidateWords.Where(w => w.Length == pattern.Length && 
                                         word.Select((c, i) => pattern[i] == '_' || 
                                                               pattern[i] == c)
                                             .All(b => b))
                                  .ToList();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜