2011-06-30 91 views
2

我正在尋找一種方法來搜索列表,該列表會根據我在該列表中進行的搜索返回一堆索引。對於前我有一個逗號分隔的字符串列表如下:C#:從列表中選擇特定的索引值

Blue, 3 
Red, 3 
Blue, 1 
Blue, 9 
Red, 5 

我想要返回我EXCEPT任何包含在標準列表中找到該文本的所有元素的索引中進行搜索。條件列表中可能包含:

Blue, 3 
Red, 5 

因此,在僞代碼,這將是,

ColorList.SelectIndex(含criteriaList的所有元素中(字)

以上應返回索引1,2,3

感謝

回答

2
var indexes = ColorList.Select((x, i) => new { Value = x, Index = i }) 
         .Where(x => !criteriaList.Contains(x.Value)) 
         .Select(x => x.Index); 

如果你的列表ç然後你可能通過首先將criteriaList轉換爲HashSet<T>得到更好的性能。 (你需要基準來確定這是否是你的情況是更好的選擇。)

var criteriaSet = new HashSet<string>(criteriaList); 
var indexes = ColorList.Select((x, i) => new { Value = x, Index = i }) 
         .Where(x => !criteriaSet.Contains(x.Value)) 
         .Select(x => x.Index); 
+0

oops:您在過濾的列表上使用索引?這將返回0,1,2(測試它) – sehe

+0

這將使用語句criteriaList.Contains(x)一次搜索整個criteriaList?它會返回colorList的索引整數值嗎? – KerryL

+0

@sehe,@KerryL:哎呀!現在修復它。 – LukeH

2
var list = new []{"Blue, 3", "Red, 3", "Blue, 1", "Blue, 9", "Red, 5"}; 
var criteria = new []{"Blue, 3", "Red, 5"}; 

var filtered = list 
     .Select((s,i)=>new {s,i}) 
     .Where(e => !criteria.Contains(e.s)) 
     .Select(e => e.i); 

結果:{ 1, 2, 3 }

+0

什麼是e.s?它究竟做了什麼? – KerryL

+0

它使用Select擴展方法的一個已知的重載(版本):http://msdn.microsoft.com/en-us/library/bb534869.aspx。這是一個'計數'枚舉器,你可以得到兩個值(s,i):字符串** _和_ **索引 – sehe

0

聽起來像是你可能需要使用一個

List<KeyValuePair<string, int>> pair = new KeyValuePair<string, int> 

那麼你可以做

foreach (KeyValuePair<string, int> p in pair){ 
    s = p.Key; 
    i = p.Value; 
} 

得到的值

+1

這是什麼解決方法?如果你想這樣做,只需做'list.Select((s,i)=> new {s,i})。ToDictionary(e => e.i,e => e.s)';但是,它直接使用'list [n]'增加_little_。 – sehe

+0

我的主要觀點是,不是將值存儲在字符串列表中,我相信使用KeyValuePairs列表會更容易,更容易混淆。特別是如果您計劃使用此列表進行超過此搜索。但是對於他們自己。 – Reed

0

我不太清楚你想在這裏實現什麼,所以也許我的答案不是你要找的。

無論如何,在通用列表中,您可以在集合上使用lambda表達式/ linq語句。考慮我寫給你們的這些例子:

internal class ListLambdaLINQSample 
{ 

    List<KeyValuePair<Colors, int>> listSource; 
    List<KeyValuePair<Colors, int>> listCriteria; 
    List<KeyValuePair<Colors, int>> listMatches; 

    private const int COLORCODE1 = 1; 
    private const int COLORCODE2 = 2; 
    private const int COLORCODE3 = 3; 
    private const int COLORCODE4 = 4; 
    private const int COLORCODE5 = 5; 

    internal enum Colors 
    { 
     Red, Blue, Green, Yellow 
    } 


    public ListLambdaLINQSample() 
    { // populate the list 
     listSource = new List<KeyValuePair<Colors, int>>(); 
     listCriteria = new List<KeyValuePair<Colors, int>>(); 

     _populateListCriteria(); 
     _populateListSource(); 

     ... 
    } 

    private void _getMatchesWithLINQ() 
    { 
     listMatches = 
         (from kvpInList 
          in listSource 
         where !listCriteria.Contains(kvpInList) 
         select kvpInList).ToList(); 
    } 

    private void _getMatchesWithLambda() 
    { 
     listMatches = 
      listSource.Where(kvpInList => !listCriteria.Contains(kvpInList)).ToList(); 
    } 


    private void _populateListSource() 
    { 
     listSource.Add(new KeyValuePair<Colors, int>(Colors.Blue, COLORCODE1)); 
     listSource.Add(new KeyValuePair<Colors, int>(Colors.Green, COLORCODE2)); 
     listSource.Add(new KeyValuePair<Colors, int>(Colors.Red, COLORCODE3)); 
     listSource.Add(new KeyValuePair<Colors, int>(Colors.Yellow, COLORCODE4)); 
    } 

    private void _populateListCriteria() 
    { 
     listCriteria.Add(new KeyValuePair<Colors, int>(Colors.Blue, COLORCODE1)); 
     listCriteria.Add(new KeyValuePair<Colors, int>(Colors.Green, COLORCODE2)); 
    } 
} 

希望這有助於!

問候, 尼科

PS:我沒有編制,也沒有測試此代碼。

2
void Main() 
{ 
    var data = new List<string> {"Blue, 3", "Red, 3", "Blue, 1", "Blue, 9", "Red, 5"}; 

    var colorList = new List<string> {"Blue, 3", "Red, 5"}; 

    var indexes = data.Except(colorList).Select (x => data.IndexOf(x)); 

    indexes.Dump(); 
}