2013-07-15 30 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在这里,但它是一个扩展方法,你想这样做