2013-07-15 57 views
2

我有一個列表List<string>與一些路徑。LINQ用於刪除從列表中的其他元素開始的元素

C:\Dir\Test\ 
C:\MyDir\ 
C:\YourDir\ 
C:\Dir\ 

我想通過所有元素(使用LINQ)並刪除從我的列表中的其他元素開始的條目。

在我的示例中C:\Dir\Test\C:\Dir\開頭 - 所以我想刪除C:\Dir\Test\

+1

爲什麼呢? –

+2

它們都以C:\開頭,不會刪除除了一個之外的所有內容嗎? – Sayse

+0

只有'C:\\'在列表中@Sayse – Cornelius

回答

9

使用List<T>.RemoveAll()方法:

sourceList.RemoveAll(x => sourceList.Any(y => x != y && x.StartsWith(y))); 
+0

所有的'x'都會在sourceList中有iterable的項目。 – Cornelius

+0

@Cornelius你是對的!查看我的更新。 – MarcinJuraszek

+0

如果相同的字符串在兩次之內會怎麼樣 –

3

試試這個:

myInitialList.RemoveAll(x =>myInitialList.Any(q => q != x && q.StartsWith(x))); 

或者,如果你想保持原來的名單,這是一種方式來獲得所有不符合你條件的記錄:

List<string> resultList = myInitialList.Except(x => myInitialList.Any(q => q != x && q.StartsWith(x))); 
+0

也將從示例中刪除'C:\ Dir \',因爲'C:\ Dir \ Test \'和'C:\ Dir \'以'C:\ Dir \ :)開頭:) – wudzik

+0

Ohw yes的確,同樣的事情Marcin首先。將編輯答案 – Tikkes

+0

重複項目如何? –

1

如何

mylist = mylist.Where(a => mylist.All(b => b == a || !a.StartsWith(b))) 
       .Distinct() 
       .ToList(); 

這將返回一個新的列表,其中沒有列表中的另一個項目以它開頭。

它有額外的檢查,以允許返回字符串相同的值,否則所有項目將從列表中刪除。

最後,不同的調用意味着刪除了兩次出現的相同字符串。在nsinreal的評論和解決方案

大廈,你可以做類似

myList = myList.OrderBy(d => d) 
.Aggregate(new List<string>(), 
    (list, item) => { 
     if (!list.Any(x => item.StartsWith(x))) 
      list.Add(item); 

     return list; 
    }).ToList(); 

這樣可以減少搜索列表的大小爲每個測試降低了解決方案的複雜性。它仍然需要初始排序。

就我個人而言,我覺得這種替代解決方案難以閱讀,我的第一個答案是更具表達性的問題來解決。

+0

這是'O(n^2)'解決方案。 –

1

最有效的方法是海事組織的路徑進行排序,然後遍歷它們,只返回那些未起以前,也就是一個:一些注意事項

public static IEnumerable<string> 
GetRootPathsOfSet(this IEnumerable<string> paths) 
{ 
    var sortedSet = new SortedSet<string>(paths, 
              StringComparer.CurrentCultureIgnoreCase); 
    string currRoot = null; 
    foreach (var p in sortedSet) 
    { 
     if (currRoot == null || 
      !p.StartsWith(currRoot, StringComparison.InvariantCultureIgnoreCase)) 
     { 
      currRoot = p; 
      yield return currRoot; 
     } 
    } 
} 

  • 所有路徑必須以尾部反斜槓終止,否則StartsWith方法不安全(例如C:\DirC:\Directory
  • 此代碼使用不區分大小寫的比較
  • 我不使用純LINQ在這裏,但它是一個擴展方法,你想這樣做