2012-07-19 54 views
6

我想将此代码转换为linq解决方案。它的功能是查看一批客户,并查看是否至少有一个中间名。此代码工作正常,我只是想学习LINQ,所以寻找一个替代的解决方案:集合中的第一个匹配

//Customers - List<Customer> 
private bool checkMiddleName() 
{ 
    foreach (Customer i in Customers) 
    { 
     if (i.HasMiddleName == true) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

我试着写类似:(Customers.Foreach(x=>x.HasMiddleName==true)... 但看起来线它不是我要找的方法。

+0

仅供参考 - 上列出的ForEach方法只执行给定的功能列表 – cordialgerm 2012-07-19 22:40:14

回答

18

如果你只是想知道,如果那里有至少一个,你可以使用Enumerable.Any

bool atLeastOneCustomerWithMiddleName = Customers.Any(c => c.HasMiddleName); 

如果您想知道第一个匹配的客户Tomer的,你可以使用Enumerable.FirstEnumerable.FirstOrDefault找到第一个客户与MiddleName==true

var customer = Customers.FirstOrDefault(c => c.HasMiddleName); 
if(customer != null) 
{ 
    // there is at least one customer with HasMiddleName == true 
} 

First引发InvalidOperationException如果源序列是空的,而FirstOrDefault回报null如果没有匹配。

+0

任何方式从查询返回true或false? – user194076 2012-07-19 22:34:58

+0

@ user194076:如果您想检查是否有一位匹配的客户,可以使用“任意”。编辑我的答案。 – 2012-07-19 22:37:41

1

在此基础上:

它所做的看起来成客户的集合,看看的至少一个有一个中间名。

尝试

return Customers.Where(x => x.HasMiddleName).Any(); 

该查询返回true如果至少一个custmer拥有财产HasMiddleName = true

+1

尼斯的每个成员 - 任何就是我一直在寻找。谢谢! – user194076 2012-07-19 22:36:11

+6

'Any'需要一个谓词,所以你可以缩短这个'return Customers.Any(x => x.HasMiddleName);' – 2012-07-19 22:39:05

2
var result = Customers.Where(x=>x.HasMiddleName == true).FirstOrDefault(); 
0

您可以使用以下方法来达到你需要的东西:

Customers.Where(cust=> cust.HasMiddleName).Count > 0 

所以,如果计数大于零意味着你有一些客户谁拥有中间名。

或者有更好的表现你会说:

bool customerWithMiddleName; 

foreach(Customer cust in Customers) 
{ 
    if(cust.HasMiddleName) 
    { 
    customerWithMiddleName = true; 
    break; 
    } 
} 
+1

这不是一个好主意,因为它执行整个查询,只知道是否有一个匹配元素。考虑到客户包含1000000个客户,并且第一个具有中间名。任何(cust => cust.HasMiddleName)'会立即返回'true',而你的方法会在返回之前检查每个元素。 – 2012-07-19 22:42:08

+2

这需要代码来计算有多少正确的项目,而不是第一次找到匹配时进行短路。这可能是不必要的昂贵。最好使用.Any()。 – StriplingWarrior 2012-07-19 22:43:30