如何筛选列表,以便没有成员是另一个成员的子字符串

NHe*_*ead 6 c# linq distinct

我有一个包含字符串项的列表,但是一些字符串包含类似的文本,我试图获取不同的列表.

我的清单包含:

-Customers\\Order1
-Customers\\Order1\\Product1
-Customers\\Order2\\Product1
-Customers\\Order2\\Product1\\Price
Run Code Online (Sandbox Code Playgroud)

从这个列表我需要得到:

-Customers\\Order1\\Product1
-Customers\\Order2\\Product1\\Price
Run Code Online (Sandbox Code Playgroud)

基本上我想省略一个字符串,如果它在列表中的另一个字符串中?

Hab*_*bib 6

你可以用一些LINQ和一个foreach循环来做到这一点:

List<string> outputList = new List<string>();
foreach (var str in originalList)
{
    if (!outputList.Contains(str)
        && !originalList.Any(r => r!= str && r.Contains(str)))
    {
        outputList.Add(str);
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑到您originalList的定义为:

List<string> originalList = new List<string>
{
    "Customers\\Order1",
    "Customers\\Order1\\Product1",
    "Customers\\Order2\\Product1",
    "Customers\\Order2\\Product1\\Price",
};
Run Code Online (Sandbox Code Playgroud)

你会得到outputList:

Customers\\Order1\\Product1
Customers\\Order2\\Product1\\Price
Run Code Online (Sandbox Code Playgroud)

  • 这看起来不错.也许`StartsWith`在这种情况下会是更好的选择 (2认同)

Joh*_*ner 5

如果这些值是真正的路径并且您想要处理子目录,则需要确保您还处理名称是另一个名称的子字符串的情况,但它们是不同的路径.IE Customer\\Order1Customer\\Order10.

public static class Extensions
{
    public static IEnumerable<string> DistinctBySubString(this IEnumerable<string> strings)
    {
        var results = new List<string>();
        foreach (var s in strings)
        {
            bool add = true;
            for(int i=results.Count-1; i>=0; i--)
            {
                if (IsSubDirectoryOf(results[i],s))
                {
                    results.RemoveAt(i);
                }
                else if (IsSubDirectoryOf(s,results[i]))
                {
                    add = false;
                }

            }
            if (add)
                results.Add(s);
        }
        return results;
    }

    private static bool IsSubDirectoryOf(string dir1, string dir2)
    {
        DirectoryInfo di1 = new DirectoryInfo(dir1);
        DirectoryInfo di2 = new DirectoryInfo(dir2);
        bool isParent = false;
        while (di2.Parent != null)
        {
            if (di2.Parent.FullName == di1.FullName)
            {
                isParent = true;
                break;
            }
            else di2 = di2.Parent;
        }
        return isParent;
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

List<string> strings = new List<string>()
{
    "Customers\\Order1",
    "Customers\\Order10",
    "Customers\\Order1\\Product1",
    "Customers\\Order2\\Product1",
    "Customers\\Order2\\Product1\\Price"
};



foreach (var result in strings.DistinctBySubString())
{
    Console.WriteLine(result);
}
Run Code Online (Sandbox Code Playgroud)

目录匹配基于此答案的代码:给定完整路径,检查路径是否是某个其他路径的子目录,否则


Jer*_*gen 3

最后一个例程的问题是,当有匹配项时,您应该中止第二个列表中的搜索。否则它对其他项目仍然有效。

编辑:新例程:

class Program
{
    private static IEnumerable<string> SelectUnique(IEnumerable<string> list)
    {
        // iterate the list..
        foreach (var item1 in list)
            // you don't want to match the same item.
            if (!list.Where(item2 => item1 != item2)
                // search for items where it start with the current item. (notice the ! before the list.Where)
                .Any(item2 => item2.StartsWith(item1)))
                    yield return item1;
    }


    static void Main(string[] args)
    {

        List<string> list = new List<string>();
        list.Add("Customers\\Order1\\Product1");
        list.Add("Customers\\Order2\\Product1");
        list.Add("Customers\\Order2\\Product1\\Price");
        list.Add("Customers\\Order1");
        list.Add("Customers\\Order3\\Price");



        var results = SelectUnique(list);

        foreach (var item in results)
            Console.WriteLine(item);

        Console.ReadKey();

    }
}
Run Code Online (Sandbox Code Playgroud)