2009-02-26 25 views
3

我有我的方法之一,下面的代碼:與LINQ查詢更換的foreach

foreach (var s in vars) 
{ 
    foreach (var type in statusList) 
    { 
     if (type.Id == s) 
     { 
      Add(new NameValuePair(type.Id, type.Text)); 
      break; 
     } 
    } 
} 

這似乎有點無效的給我,我想知道是否有辦法來代替的至少一個以LINQ查詢爲前提。有什麼建議麼?

編輯: vars是一個字符串數組,Add方法將一個項目添加到CSLA NameValueList。

回答

6

編輯:我沒有注意到的break;

如果有可能不止一種類型與相關ID,那麼就需要使用FirstOrDefaultKeith's answer或我的第二個代碼示例如下。

編輯:刪除「多從」版本,因爲它是不必要的低效率假設相等/散列碼適用於任何類型的type.Id是。

聯接可能是更合適不過:

var query = from s in vars 
      join type in statusList on s equals type.Id 
      select new NameValuePair(type.Id, type.Text); 

foreach (var pair in query) 
{ 
    Add(pair); 
} 

你可能想作出AddRange方法,它需要一個IEnumerable<NameValuePair>此時你可以只調用AddRange(query)

或者,您可以使用LookUp。該版本確保每個「s」只添加一種類型。

var lookup = types.ToLookup(type => type.Id); 
foreach (var s in vars) 
{ 
    var types = lookup[s]; 
    if (types != null) 
    { 
     var type = types.First(); // Guaranteed to be at least one entry 
     Add(new NameValuePair(type.Id, type.Text)); 
    } 
} 

這樣做的好處是它基本上只通過一次類型列表來建立字典。

2

事情是這樣的:

foreach(var s in vars) { 
    var type = statusList.FirstOrDefault(t => t.Id == s); 
    if (type != null) 
     Add(new NameValuePair(type.Id, type.Text)); 
} 

或者,如果瓦爾支持ForEach方法,這將工作太(但我建議不要overLINQifying):

vars.ForEach(s => { 
    var type = statusList.FirstOrDefault(t => t.Id == s); 
    if (type != null) 
     Add(new NameValuePair(type.Id, type.Text)); 
}); 

我認爲type是一個參考的實例類型。

+0

打我太它:-) – 2009-02-26 09:16:18

+0

我看不出如何編譯 - 你在第三行使用「type」將不起作用,因爲變量沒有在任何地方聲明。 「Any」調用中的lambda表達式不會保留。 – 2009-02-26 09:28:54

+0

喬恩,感謝您的注意!我仍然想知道我是如何犯這個愚蠢的錯誤。 – 2009-02-26 09:43:40

12

基本上:

var types = 
    from s in vars 
    let type = (
     from tp in statusList 
     where tp.Id == s).FirstOrDefault() 
    where type != null 
    select new NameValuePair(type.Id, type.Text) 
1

Bart de Smet具有用於IEnumerable的一個擴展的ForEach的實現。

2

如果您的添加方法構建一個列表,您也可以嘗試:

IEnumarable<NamedValuePair> result = statusList.Where(type => type.Id == s).Select(new NameValuePair(type => type.Id, type.Text)); 
1

我沒有看到一組答案加入,所以這裏是一個: