在C#中对StringBuilder项目列表进行重复数据删除

时间:2015-02-17 02:30:28

标签: c# linq

我遇到的情况是需要在使用StringBuilder生成的SQL select语句中重复列表列。我还需要返回一个StringBuilder对象。

我提出的解决方案,但它看起来像是一场噩梦。有人可以提出一个更清洁的方法来实现这一目

//The SQL statement is being passed to my code as a StringBuilder
//This is just scaffolding to fake that input.
StringBuilder items = new StringBuilder();
items.Append("SELECT ");
items.Append("Apple,");
items.Append("Carrot,");
items.Append("Pear,");
items.Append("Orange,");
items.Append("Apple");
items.Append(" From fruit_table");
//End scaffolding

//My code start:
//Chop off the non-important parts
items.Replace("SELECT ", "");
items.Replace(" From fruit_table", "");

//Convert string to list, seperating on commas
List<string> itemList = items.ToString().ToUpper().Split(',').ToList<string>();

//Found a handy "distinct" method in LINQ library
itemList = itemList.Distinct().ToList();

//Wipe out the original stringbuilder. For clarity and consistency with some other code, I'd like to reuse the same stringBuilder that was passed to me.
items.Clear();

//Rebuild my stringbuilder, now deduped
items.Append("SELECT ");
itemList.ForEach(x => items.Append(x + ","));
//Remove that comma after last fruit item
items.Remove((items.Length - 1), 1);
items.Append(" FROM fruit_table");

//Not really going to output to console, but you
//get the idea.
Console.WriteLine(items.ToString());
Console.ReadLine();

提前感谢您的任何帮助!

2 个答案:

答案 0 :(得分:3)

如果你坚持从StringBuilder开始,那么我认为你已经完成了你需要做的事情。

尽管如此我会让它变得更清洁:

var prefix = "SELECT ";
var suffix = " From fruit_table";
var result =
    String.Format("{0}{2}{1}",
        prefix,
        suffix,
        String.Join(",",
            items
                .ToString()
                .Replace(prefix, "")
                .Replace(suffix, "")
                .Split(',')
                .Select(x => x.Trim())
                .Distinct()));
items.Clear();
items.Append(result);

在:

SELECT Apple,Carrot,Pear,Orange,Apple From fruit_table

后:

SELECT Apple,Carrot,Pear,Orange From fruit_table

如果您知道列名称之间没有空格,那么这样就会更清晰了:

var result =
    String.Format("{0}{2}{1}",
        prefix,
        suffix,
        String.Join(",",
            items
                .ToString()
                .Split(' ')[1]
                .Split(',')
                .Distinct()));

答案 1 :(得分:3)

这是另一种方法,无需对前缀和后缀元素进行硬编码:

// Encapsulate the behavior in an extension method we can run
// directly on a StringBuilder object
public static StringBuilder DeduplicateColumns(this StringBuilder input) {
    // Assume that we can split into large "chunks" on spaces
    var sections = input.ToString().Split(' ');
    var resultSections = new List<string>();

    foreach (var section in sections) {
        var items = section.Split(',');

        // If there aren't any commas, spit this chunk back out
        // Otherwise, split on the commas and get distinct items
        if (items.Count() == 1)
            resultSections.Add(section);
        else
            resultSections.Add(string.Join(",", items.Distinct()));
    }

    return new StringBuilder(string.Join(" ", resultSections));
}

测试代码:

var demoStringBuilder = new StringBuilder
    ("SELECT Apple,Carrot,Pear,Orange,Apple From fruit_table");
var cleanedBuilder = demoStringBuilder.DeduplicateColumns();

// Output: SELECT Apple,Carrot,Pear,Orange From fruit_table

这是一个小提琴:link