2016-09-16 57 views
1

我有一個場景,其中每個組中有多個圖像,並且需要根據字符串條件提取單個圖像。基於優先級條件獲取單個項目的最有效方法

下面是它現在完成的方式,它的工作原理;然而,不知道這是最有效的方式,性能,尺寸,也許聰明的做法太

   foreach (var g in groups) 
       { 
        SomeType file = null; 

        if (file == null) 
        { 
         file = g.Where(i => 
           i.URL.Contains("StringA") 
           ).FirstOrDefault(); 
        } 
        if (file == null) 
        { 
         file = g.Where(i => 
            i.URL.Contains("StringB") 
           ).FirstOrDefault(); 
        } 
        if (file == null) 
        { 
         file = g.Where(i => 
           i.URL.Contains("StringC") 
           ).FirstOrDefault(); 
        } 
        if (file == null) 
        { 
         // etc... 
        } 
        if (file == null) 
        { 
         file = g.FirstOrDefault(); 
        } 
       } 
+1

過於寬泛:代碼風格偏離主題以至於無視那部分,大小 - 顯然你可以將它重構爲一個循環(所以這不太可能是你問的問題),性能問題 - 完全缺少任何數字和你正在使用的LINQ提供程序的類型... –

+0

有更有效的方法來做到這一點,但不是在LINQ(至少我想不出一種方式) –

+0

@AlexeiLevenkov,你能解釋一下你的意思嗎?供應商? System.Linq是常態,並且經常使用MoreLinq庫...並且它從來沒有關於無聊:)我只是從來沒有信服我的方法......我想要接觸到其他開發人員如何認爲是真棒! – usefulBee

回答

2

我怕你會發現這個答案稍顯沉悶,但我會避免試圖找到一些非常impressive-看起來很複雜但是linq查詢。我確信它可以完成但不值得頭痛。

只需將所有字符串粘貼到數組中並按優先級順序檢查它們。除非你跑過大量的物品,否則它足夠快。你沒有執行數據庫查詢 - 你的foreach循環清楚地表明你的數據已經在內存中。

所以,我會失去大的if語句和瞄準線沿線的東西:

string [] my_list = new string [] {"StringA", "StringB", "StringC"}; 

foreach (var g in groups) 
{ 
    foreach (string s in my_list) 
    { 
     file = g.Where(i => i.URL.Contains(s)).FirstOrDefault(); 
     if (file != null) 
      break; 
    } 
    if (file == null) 
    { 
     file = g.FirstOrDefault(); 
    } 
} 

就像我說的,不是很興奮,但它的死很容易改變你的重點在你的搜索和\或添加和刪除字符串。

HTH,

Adam。

+0

你所有的假設都是正確的。我只編輯了Contains語句來通過s var ...優秀方法 – usefulBee

+0

我應用了這種方法,並且完全被性能增益驚訝!它也非常靈活,可以根據應用程序需求和不同的優先級創建不同的列表。很高興我問過! – usefulBee

1
string [] my_list = new string [] {"StringA", "StringB", "StringC"}; 
foreach (var g in groups) 
{ 
    SomeType file = g.FirstOrDefault(i => my_list.Any(l=>i.Url.Contains(l))) 
            ?? g.FirstOrDefault(); 

} 
+0

不得不把我最後的評論回來;即使這種方法看起來很有前途,但並不能保證優先 - 我發現當StringA可用時有StringB和C的項目 – usefulBee

0
string[] filters = new[] { "StringA", "StringB", "StringC" }; 

foreach (var g in groups) 
{ 
    SomeType file = filters.Select(s => g.FirstOrDefault(i => i.URL.Contains(s))) 
          .FirstOrDefault(m => m != null); 
} 

或者,如果您想更換整個循環和實際存儲結果的地方:

var files = groups.Select(g => filters.Select(s => g.FirstOrDefault(i => i.URL.Contains(s))) 
             .FirstOrDefault(m => m != null)); 

BTW:表達式像

file = g.Where(somePredicate).FirstOrDefault();

可寫爲

file = g.FirstOrDefault(somePredicate);