如何在LINQ中执行此查询?

时间:2011-05-01 16:08:13

标签: c# linq

考虑这个简短的片段:

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);
    }
}

有没有办法用LINQ干净地表达这个?
它是什么?

2 个答案:

答案 0 :(得分:3)

直接的翻译是使用Zip运算符将每个候选词覆盖在模式词上。

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

如果您真的想关注指数,可以使用Range运算符:

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;

编辑:

正如David Neale所指出的,Zip运算符在.NET 4.0之前不可用。然而,自己实现它是trivial

答案 1 :(得分:0)

另一种没有Zip的方法:

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