C#字符串操作生成字符串列表

时间:2015-11-20 19:18:44

标签: c# string list

我正在尝试对产品导入进行一些字符串操作,不幸的是我有一些重复的数据,如果留在这里会将产品分配给我不希望产品分配的类别。

我有以下字符串:

A类| A类>子类别1 |类别B |类别C |类别C>子类别2

我想成为的结果:

A类>子类别1

B类

C类>子类别2

首先我分裂了(|),它给了我:

A类

A类>子类别1

B类

C类

C类>子类别2

然后我循环浏览此列表并溢出(>)

但我不知道如何合并结果,例如类别A \子类别1

以下是代码。这将用于处理大约1200行,所以我试图让它尽可能快。

    static void Main(string[] args)
    {
        string strProductCategories = "Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2";

        List<string> firstSplitResults = strProductCategories.SplitAndTrim('|');

        List<List<string>> secondSplitResults = new List<List<string>>();

        foreach( string firstSplitResult in firstSplitResults )
        {
            List<string> d = firstSplitResult.SplitAndTrim('>');
            secondSplitResults.Add(d);
        }

       // PrintResults(firstSplitResults);
        PrintResults2(secondSplitResults);
    }

    public static void PrintResults(List<string> results)
    {
        foreach( string value in results)
        {
            Console.WriteLine(value);
        }
    }

    public static void PrintResults2(List<List<string>> results)
    {
        foreach(List<string> parent in results)
        {
            foreach (string value in parent)
            {
                Console.Write(value);
            }

            Console.WriteLine(".....");
        }


    }
}

public static class StringExtensions
{
    public static List<string> SplitAndTrim(this string value, char delimter)
    {
        if( string.IsNullOrWhiteSpace( value))
        {
            return null;
        }

        return value.Split(delimter).Select(i => i.Trim()).ToList();
    }
}

一旦我获得了正确的列表,我将使用(\)。

重新加入列表

任何帮助都非常有用。

更新

数据来自CSV,因此它可以有n个级别。

例如:

A类 - &gt;这是数据冗余

A类&gt;子类别1 - &gt;这是数据冗余

A类&gt;子类别1&gt;次级别类别1

A类&gt;子类别1&gt;次级别类别2

会导致:

A类&gt;子类别1&gt;次级别类别1

A类&gt;子类别1&gt;次级别类别2

西蒙

4 个答案:

答案 0 :(得分:0)

你有一个良好的开端,基本上你只需要在最后添加一些代码来完成解决方案。

foreach( List<string> i in secondSplitResults )
{
     if (i.Count == 2)
     {
        i.RemoveAll(x => x.Count == 1 && x[0] == i[0]);
        i.Insert(1,"/");
    }
}

PrintResults2(secondSplitResults);

答案 1 :(得分:0)

如果叶子元素标记为&#34;冗余&#34;删除问题可以减少到找到具有共同前缀的项目中最长的路径:

class Program
{
    static void Main(string[] args)
    {
        string pathCase1 = "Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2";
        string pathCase2 = "Category A -> THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 -> THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 > Sub Sub Category 1|Category A > Sub Category 1 > Sub Sub Category 2";
        PrintPaths("case1", ParsePaths(pathCase1));
        PrintPaths("case2", ParsePaths(pathCase2));

        Console.ReadLine();
    }

     private static void PrintPaths(string name, List<string> paths)
     {

         Console.WriteLine(name);
         Console.WriteLine();

         foreach (var item in paths)
         {
             Console.WriteLine(item);
         }

         Console.WriteLine();
     }



    static string NormalizePath(string src)
    {
        // Remove "-> THIS DATA IS REDUNDANT" elements

        int idx = src.LastIndexOf('>');
        if (idx > 0 && src[idx - 1] == '-')
        {
            src = src.Substring(0, idx - 1);
        }

        var parts = src.SplitAndTrim('>');
        return string.Join(">", parts);
    }


     static List<string> ParsePaths(string text)
     {
         var items = text.SplitAndTrim('|');
         for (int i = 0; i < items.Count; ++i)
         {
             items[i] = NormalizePath(items[i]);
         }

         items.Sort();

         var longestPaths = new SortedSet<string>();

         foreach (var s in items)
         {
             int idx = s.LastIndexOf('>');
             if (idx > 0)
             {
                 var prefix = s.Substring(0, idx);
                 longestPaths.Remove(prefix);
             }

             longestPaths.Add(s);
         }

         return longestPaths.ToList();
     }
}

<强>输出:

case1

Category A>Sub Category 1
Category B
Category C>Sub Category 2

case2

Category A>Sub Category 1>Sub Sub Category 1
Category A>Sub Category 1>Sub Sub Category 2

答案 2 :(得分:0)

我可能误解了这个问题,但也许我在两行代码中做到了这一点:

https://dotnetfiddle.net/GyDwar

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        foreach(var part in getParts("Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2"))
            Console.WriteLine(part);
        Console.WriteLine();

        Console.WriteLine("TEST 2");
        foreach(var part in getParts("Category A > THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 > THIS IS DATA IS REDUNDANT|Category A > Sub Category 1 > Sub Sub Category 1|Category A > Sub Category 1 > Sub Sub Category 2"))
            Console.WriteLine(part);
    }

    public static List<string> getParts(string stringToParse){
        var parts = stringToParse.Split('|').Select(part => part.Trim());
        return parts.Where(part => !parts.Any(comparePart => part != comparePart && comparePart.StartsWith(part))).ToList();
    }
}

<强>结果:

Category A > Sub Category 1
Category B
Category C > Sub Category 2

TEST 2
Category A > THIS IS DATA IS REDUNDANT
Category A > Sub Category 1 > THIS IS DATA IS REDUNDANT
Category A > Sub Category 1 > Sub Sub Category 1
Category A > Sub Category 1 > Sub Sub Category 2

我基本上说把所有部分都放在另一部分的开头。

答案 3 :(得分:0)

在(|)上拆分后,浏览此列表并简单地计算初始字符串中每个列表项字符串的出现次数。如果初始字符串中的项目出现次数大于1,则应删除此项目。结果列表将是您所需要的。我在这里采用的初始字符串中计算每个列表项字符串的出现次数How would you count occurrences of a string within a string?,这看起来是最快的方法

    string strProductCategories = "Category A|Category A > Sub Category 1|Category B|Category C|Category C > Sub Category 2";

    List<string> firstSplitResults = strProductCategories.SplitAndTrim('|');

    for (int i = 0; i < firstSplitResults.Count; i++)
    {
        int occCount = (strProductCategories.Length - strProductCategories.Replace(firstSplitResults[i], "").Length) / firstSplitResults[i].Length;
        if (occCount > 1)
        {
            firstSplitResults.RemoveAt(i);
            i--;
        }
    }

    // print result
    for (int i = 0; i < firstSplitResults.Count; i++)
    {
        Console.WriteLine(firstSplitResults[i]);
    }
    Console.ReadLine();