C# 将对象集合加入以逗号分隔的字符串中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/330493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:28:13  来源:igfitidea点击:

Join collection of objects into comma-separated string

c#.net.net-3.5

提问by Helen Toomik

In many places in our code we have collections of objects, from which we need to create a comma-separated list. The type of collection varies: it may be a DataTable from which we need a certain column, or a List<Customer>, etc.

在我们代码的很多地方,我们都有对象集合,我们需要从中创建一个逗号分隔的列表。集合的类型各不相同:它可能是我们需要某个列的 DataTable,或 List<Customer> 等。

Now we loop through the collection and use string concatenation, for example:

现在我们遍历集合并使用字符串连接,例如:

string text = "";
string separator = "";
foreach (DataRow row in table.Rows)
{
    text += separator + row["title"];
    separator = ", ";
}

Is there a better pattern for this? Ideally I would like an approach we could reuse by just sending in a function to get the right field/property/column from each object.

有没有更好的模式呢?理想情况下,我想要一种我们可以重用的方法,只需发送一个函数即可从每个对象中获取正确的字段/属性/列。

采纳答案by Hosam Aly

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

public delegate string Indexer<T>(T obj);

public static string concatenate<T>(IEnumerable<T> collection, Indexer<T> indexer, char separator)
{
    StringBuilder sb = new StringBuilder();
    foreach (T t in collection) sb.Append(indexer(t)).Append(separator);
    return sb.Remove(sb.Length - 1, 1).ToString();
}

// version for non-generic collections
public static string concatenate<T>(IEnumerable collection, Indexer<T> indexer, char separator)
{
    StringBuilder sb = new StringBuilder();
    foreach (object t in collection) sb.Append(indexer((T)t)).Append(separator);
    return sb.Remove(sb.Length - 1, 1).ToString();
}

// example 1: simple int list
string getAllInts(IEnumerable<int> listOfInts)
{
    return concatenate<int>(listOfInts, Convert.ToString, ',');
}

// example 2: DataTable.Rows
string getTitle(DataRow row) { return row["title"].ToString(); }
string getAllTitles(DataTable table)
{
    return concatenate<DataRow>(table.Rows, getTitle, '\n');
}

// example 3: DataTable.Rows without Indexer function
string getAllTitles(DataTable table)
{
    return concatenate<DataRow>(table.Rows, r => r["title"].ToString(), '\n');
}

回答by Galwegian

As an aside: The first modification I would make is to use the StringBuilder Classinstead of just a String - it'll save resources for you.

顺便说一句:我要做的第一个修改是使用StringBuilder 类而不仅仅是一个字符串——它会为你节省资源。

回答by Matt Howells

static string ToCsv<T>(IEnumerable<T> things, Func<T, string> toStringMethod)
{
    StringBuilder sb = new StringBuilder();

    foreach (T thing in things)
        sb.Append(toStringMethod(thing)).Append(',');

    return sb.ToString(0, sb.Length - 1); //remove trailing ,
}

Use like this:

像这样使用:

DataTable dt = ...; //datatable with some data
Console.WriteLine(ToCsv(dt.Rows, row => row["ColName"]));

or:

或者:

List<Customer> customers = ...; //assume Customer has a Name property
Console.WriteLine(ToCsv(customers, c => c.Name));

I don't have a compiler to hand but in theory it should work. And as everyone knows, in theory, practice and theory are the same. In practice, they're not.

我手头没有编译器,但理论上它应该可以工作。众所周知,在理论上,实践和理论是相同的。在实践中,他们不是。

回答by Mendelt

You could write a function that transforms a IEnumerable into a comma separated string

您可以编写一个将 IEnumerable 转换为逗号分隔字符串的函数

public string Concat(IEnumerable<string> stringList)
{
    StringBuilder textBuilder = new StringBuilder();
    string separator = String.Empty;
    foreach(string item in stringList)
    {
        textBuilder.Append(separator);
        textBuilder.Append(item);
        separator = ", ";
    }
    return textBuilder.ToString();
}

You can then use Linq to query your collection/dataset/etc to provide the stringList.

然后,您可以使用 Linq 查询您的集合/数据集/等以提供 stringList。

回答by leppie

string.Join(", ", Array.ConvertAll(somelist.ToArray(), i => i.ToString()))

回答by leppie

string strTest = "1,2,4,6";
string[] Nums = strTest.Split(',');
Console.Write(Nums.Aggregate<string>((first, second) => first + "," + second));
//OUTPUT:
//1,2,4,6

回答by BigBlondeViking

I love Matt Howells answerin this post:

我喜欢 Matt Howells在这篇文章中的回答

I had to make it into an extension:

我不得不把它变成一个扩展:

public static string ToCsv<T>(this IEnumerable<T> things, Func<T, string> toStringMethod)

Usage: [ I am getting all the emails and turning them into a csv string for emails ]:

用法:[我正在获取所有电子邮件并将它们转换为电子邮件的 csv 字符串]:

var list = Session.Find("from User u where u.IsActive = true").Cast<User>();

return list.ToCsv(i => i.Email);

回答by Ian Mercer

In .NET 4 you can just do string.Join(", ", table.Rows.Select(r => r["title"]))

在 .NET 4 中你可以做 string.Join(", ", table.Rows.Select(r => r["title"]))

回答by Umang Patel

I found string.Join and Lambda Select> helps to write minimum code.

我发现 string.Join 和 Lambda Select> 有助于编写最少的代码。

        List<string> fruits = new List<string>();
        fruits.Add("Mango");
        fruits.Add("Banana");
        fruits.Add("Papaya");

        string commaSepFruits = string.Join(",", fruits.Select(f => "'" + f + "'"));
        Console.WriteLine(commaSepFruits);

        List<int> ids = new List<int>();
        ids.Add(1001);
        ids.Add(1002);
        ids.Add(1003);

        string commaSepIds = string.Join(",", ids);
        Console.WriteLine(commaSepIds);

        List<Customer> customers = new List<Customer>();
        customers.Add(new Customer { Id = 10001, Name = "John" });
        customers.Add(new Customer { Id = 10002, Name = "Robert" });
        customers.Add(new Customer { Id = 10002, Name = "Ryan" });

        string commaSepCustIds = string.Join(", ", customers.Select(cust => cust.Id));
        string commaSepCustNames = string.Join(", ", customers.Select(cust => "'" + cust.Name + "'"));

        Console.WriteLine(commaSepCustIds);
        Console.WriteLine(commaSepCustNames);

        Console.ReadLine();

回答by toddmo

Here's my favorite answer adapted to the question, and corrected Convert to ConvertAll:

这是我最喜欢的适合该问题的答案,并更正了 Convert to ConvertAll:

string text = string.Join(", ", Array.ConvertAll(table.Rows.ToArray(), i => i["title"]));