2012-12-19 31 views
1

列表的第一個值看似簡單的問題: 我有一個字符串列表(從屬性文件中讀取):LINQ的發現在其他列表

IList<string> defaultValues = new List<string> {"0458","0309"}; 

和一些物品的另一個列表,每一個都具有財產字符串類型:

IList<Token> tokens = new List<Token> 
{ 
    new Token {DisplayValue = "0123"}, 
    new Token {DisplayValue = "0309"}, 
    new Token {DisplayValue = "0203"}, 
    new Token {DisplayValue = "0458"}, 
    new Token {DisplayValue = "0911"} 
}; 

public class Token 
{ 
    public string DisplayValue { get; set; } 
} 

現在我想獲得的令牌,其中DisplayValue defaultValues的第一個元素(0485)相匹配的元素。如果找不到具有DisplayValue 0485的元素,則defaultvalues中的第二個元素應該匹配(0309),依此類推。

defaultValues列表可以是動態的,所以可以添加更多的值,並且總是第一個條目應該具有優先級。

因此,defaultValues列表是排序字符串的優先級列表,索引越低優先級越高。 在上面的例子中,結果應該是「0458」。

我可以做這樣的事情:

string result = string.Empty; 

foreach (var searchValue in defaultValues) 
{ 
    if (tokens.Any(token => token.DisplayValue == searchValue)) 
    { 
     result = searchValue; 
    } 
} 

但我覺得這樣的事情可以更典雅,並沒有做的foreach ...

回答

2

使用Any在這種情況下,這可能不是最高效的一個爲O(n^2)。可能最好的辦法是做一個GroupJoin(改爲O(n)),然後選擇匹配的第一個標記。請記住,GroupJoin只對完全匹配的鍵進行操作,所以如果您正在查找比較或子字符串搜索,則必須找到其他方法。

defaultValues 
    .GroupJoin(
     tokens, // matching 0:n tokens per default value 
     defVals => defVals, // key selector for our left source 
     tks => tks.DisplayValue, // key selector for our right source 
     (defVal, tks) => tks.FirstOrDefault()) // result selector for our matches 
    .FirstOrDefault(match => match != null) 

這樣做的唯一橫貫每收集一次的優勢,所有令牌與相應DefaultValue匹配(所以你可以有每個缺省值的多個匹配)。你可以做defaultValues.FirstOrDefault(x => tokens.Any(t => t == x)),但你會遇到同樣的問題(可能O(n^2)的複雜性)。從這裏開始,你可以檢查它是否爲空(使用null合併)並在Token中添加一個名爲Empty的靜態常量,該常量初始化爲new Token { DisplayValue = string.Empty }。之後,你可以這樣做:

(defaultValues 
    .GroupJoin(
     ... 
    .FirstOrDefault(match => match != null) ?? Token.Empty).DisplayValue 
+0

輝煌,謝謝! –

0

基本上你需要尋找從投影你的Linq/Lambada結果。

我會嘗試這樣的事:

var macthes = tokens.Any(t => t.DisplayValue.In(defaultValues)) 
       .Select(y =>y.DisplayValue); 
相關問題