2015-10-20 108 views
1

是否有一種更優雅的方式來使用LINQ實現下面的代碼? 基本上我想要得到一個列表中的所有索引,其中列表中的字符串出現在另一個列表中。獲取列表中的字符串索引<string>

private List<int> GetColumnIndexesToIgnore(
    ReadOnlyCollection<string> listOfColumnsToIgnore, List<string> columnHeadings) 
{ 
    List<int> columnIndexesToIgnore = new List<int>(); 
    for (int i = 0; i < columnHeadings.Count; i++) 
    { 
     if (listOfColumnsToIgnore.Contains(columnHeadings[i])) 
     { 
      columnIndexesToIgnore.Add(i); 
     } 
    } 
    return columnIndexesToIgnore; 
} 

回答

6

你可以用LINQ像這樣做:

var res = columnHeadings 
    .Select((v, i) => new {Value = v, Index = i}) 
    .Where(p => listOfColumnsToIgnore.Contains(p.Value)) 
    .Select(p => p.Index) 
    .ToList(); 

第一Select對值和他們的指標,Where條款過濾掉你不想對,第二Select收成索引返回,ToList使List<int>不在其中。

+0

此外,它也能夠丟棄'ToList()'和如果這符合OP的要求,則將方法的返回更改爲'IEnumerable '以獲得惰性評估的好處。 – jdphenix

+0

備註:如果你有大量的項目將'listOfColumnsToIgnore'轉換爲'HashSet '首先可能是有益的(嘗試和衡量)。 –

+1

@jdphenix返回'IEnumerable '的問題是可能枚舉多次而沒有真正注意。我在一個方法中使用'IEnumerable's,但是在大多數情況下返回結果之前我只是爲了避免多個枚舉的可能性而將結果轉換爲列表。 – dasblinkenlight

2

你可以得到滿足和-1爲其他的項目的索引,然後篩選出-1值:

List<int> columnIndexesToIgnore = columnHeadings 
    .Select((c, i) => listOfColumnsToIgnore.Contains(c) ? i : -1) 
    .Where(i => i != -1) 
    .ToList(); 
相關問題