是否可以将这两个语句组合成一个返回“包含”和“不包含”结果的语句?
string[] words = { "one", "two", "three", "four" };
int[] numbers = { 4, 5, 6 };
string[] contains =
(from w in words
where numbers.Contains(w.Length)
select w).ToArray();
string[] notContains =
(from w in words
where !numbers.Contains(w.Length)
select w).ToArray();
答案 0 :(得分:8)
你可以这样做:
var groups = words.GroupBy(w => numbers.Contains(w.Length));
这最多会返回两组:一组使用键false
,另一组使用键true
。
正如vc 74在注释中指出的那样,numbers.Contains
是numbers
是数组时的O(n)操作。将它转换为HashSet将使这成为一个恒定的时间操作,渐进地快得多。
所以,这是更新后的代码:
var numberHS = new HashSet<int>(numbers);
var groups = words.GroupBy(w => numberHS.Contains(w.Length));
答案 1 :(得分:6)
您还可以使用ToLookup
:
var containsLengthLookup = words.ToLookup(w => numbers.Contains(w.Length));
string[] contains = containsLengthLookup[true].ToArray();
string[] notContains = containsLengthLookup[false].ToArray();
如果其中一个为空(或源数组为空),则为空string[]
。
与GroupBy
存在一个区别,查询被缓存。因此,如果您多次使用它会更有效,但信息只是一个快照。如果您修改words
或numbers
,则不会在查找中反映出来。