string.Join on a List <int> hoặc kiểu khác


86

Tôi muốn biến một mảng hoặc danh sách các int thành một chuỗi được phân tách bằng dấu phẩy, như sau:

string myFunction(List<int> a) {
    return string.Join(",", a);
}

Nhưng string.Join chỉ nhận List<string>tham số thứ hai. Cách tốt nhất để làm việc này là gì?


2
Bạn đang sử dụng phiên bản C # / .NET nào?
Mark Byers

Có thể có bản sao của stackoverflow.com/questions/3211422/…
goodeye,

Câu trả lời:


149

Cách tốt nhất là nâng cấp lên .NET 4.0 khi quá tải có thể thực hiện những gì bạn muốn:

Nếu bạn không thể nâng cấp, bạn có thể đạt được hiệu quả tương tự bằng cách sử dụng Select và ToArray.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());

Cũng cho rằng ông là ít nhất là trên C # 3, .NET 3.5
Anthony Pegram

Tại sao lại sử dụng LINQ thay vì ToArrayphương thức tích hợp sẵn của List<T>?
Steven Sudit,

2
bởi vì anh ta sẽ có một Danh sách <int>. Lựa chọn linq chuyển đổi Danh sách <int> thành IEnumerable <string> và sau đó thành mảng.
Greg Bogumil,

Nâng cấp lên 4.0 là không thực tế trong tình huống của tôi, nhưng giải pháp LINQ chính là thứ tôi đang tìm kiếm. Cảm ơn!
Code Commander

1
@gbogumil: Xin lỗi, tôi không nhận thấy đó là một int.
Steven Sudit,

5

Một khả năng mở rộngan toàn thi hành một chuỗi đếm được generic tham gia cho .NET 3.5. Việc sử dụng các trình vòng lặp là để giá trị chuỗi tham gia không bị mắc kẹt ở cuối chuỗi. Nó hoạt động chính xác với 0, 1 và nhiều phần tử hơn:

public static class StringExtensions
{
    public static string Join<T>(this string joinWith, IEnumerable<T> list)
    {
        if (list == null)
            throw new ArgumentNullException("list");
        if (joinWith == null)
            throw new ArgumentNullException("joinWith");

        var stringBuilder = new StringBuilder();
        var enumerator = list.GetEnumerator();

        if (!enumerator.MoveNext())
            return string.Empty;

        while (true)
        {
            stringBuilder.Append(enumerator.Current);
            if (!enumerator.MoveNext())
                break;

            stringBuilder.Append(joinWith);
        }

        return stringBuilder.ToString();
    }
}

Sử dụng:

var arrayOfInts = new[] { 1, 2, 3, 4 };
Console.WriteLine(",".Join(arrayOfInts));

var listOfInts = new List<int> { 1, 2, 3, 4 };
Console.WriteLine(",".Join(listOfInts));

Thưởng thức!


+1: Đây là cách ưa thích của tôi trước .NET 4.0. Khả năng mở rộng hơn nhiều so với việc tạo ra một mảng chuỗi hoàn toàn mới từ danh sách các int để String.Join(String, String[])có thể được gọi. Chỉ có điều tôi muốn nói là thật bất thường khi thấy phương thức này được viết dưới dạng phần mở rộng thay StringIEnumerable<String>- tôi có xu hướng luôn gọi nó ở cuối một chuỗi dài các lệnh gọi phương thức mở rộng.
Alex Humphrey,

2
Tôi đã đánh cắp ý tưởng từ Python nếu đó là bất kỳ sự trợ giúp nào!
Đã xóa

4

.NET 2.0:

static string IntListToDelimitedString(List<int> intList, char Delimiter)
{
    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < intList.Count; i++)
    {
        builder.Append(intList[i].ToString());

        if (i != intList.Count - 1)
            builder.Append(Delimiter);
    }

    return builder.ToString();
}

3
Một cách tiếp cận 2.0 tốt. Bạn có thể muốn đặt ký tự nối thành một tham số thay vì mã hóa cứng nó vào phương thức.
Anthony Pegram,

Một tối ưu hóa điển hình là thêm dấu phân cách mà không cần kiểm tra, sau đó xóa ký tự cuối cùng khi bạn thoát ra khỏi vòng lặp.
Steven Sudit,

@Steven - Tôi đã suy nghĩ về nó, nhưng tôi nghĩ điều này cũng sẽ phụ thuộc vào độ dài của chuỗi (nếu không kiểm tra, tôi không chắc chắn), vì vậy tôi mắc kẹt với kiểm tra bool đơn giản.
Kyle Rosendo

Tôi nghi ngờ việc tối ưu hóa sẽ chỉ có thể đo lường được đối với các chuỗi dài. Phải nói rằng, tôi không nghĩ rằng nó sẽ chậm hơn đối với những bài ngắn.
Steven Sudit,

2

Câu trả lời này dành cho bạn nếu bạn chưa muốn dấn thân vào chiều sâu của .NET 4.0.

String.Join () nối tất cả các phần tử của một mảng chuỗi, sử dụng dấu phân cách được chỉ định giữa mỗi phần tử.

Cú pháp là

public static string Join(
    string separator,
    params string[] value
)

Thay vì chuyển Danh sách các int của bạn sang phương thức Join, tôi khuyên bạn nên tạo một mảng chuỗi trước.

Đây là những gì tôi đề xuất:

static string myFunction(List<int> a) {
    int[] intArray = a.ToArray();
    string[] stringArray = new string[intArray.Length];

    for (int i = 0; i < intArray.Length; i++)
    {
        stringArray[i] = intArray[i].ToString();
    }

    return string.Join(",", stringArray);
}

3
Đây là một cách tiếp cận phù hợp nếu ai đó vẫn đang sử dụng 2.0. Tuy nhiên, intArraylà không cần thiết. List<int>có thể lập chỉ mục và có một thuộc Counttính, làm cho việc chuyển đổi thành một mảng là không cần thiết. Bạn cũng có thể muốn đặt ký tự nối thành một tham số thay vì mã hóa cứng nó vào phương thức.
Anthony Pegram,

2

Có một Phương pháp mở rộng tương tự mà tôi đã sửa đổi thành này

public static class MyExtensions
{
    public static string Join(this List<int> a, string splitChar)
    {
        return string.Join(splitChar, a.Select(n => n.ToString()).ToArray());
    }
}

và bạn sử dụng nó như thế này

var test = new List<int>() { 1, 2, 3, 4, 5 };
string s = test.Join(",");

.NET 3.5


Không chắc tôi thích điều này. IEnumerable<T>đã có một Joinphương thức và phương thức mới này thực hiện một hoạt động hoàn toàn khác, khiến việc sử dụng nó trở nên phản trực giác. Thứ hai, nếu bạn đang đi để tạo ra phương pháp này, đi trước và làm cho nó quát áp dụng.
Anthony Pegram,

Đó là một bản hack bắt chước phương thức nối trên các mảng trong Ruby. ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström,

Ngoài ra .ToString () không phải lúc nào cũng trả về biểu diễn chuỗi của T vì vậy tôi đoán rằng điều đó thực sự có thể gây ra một số nhầm lẫn.
Jonas Elfström,

2

Sử dụng .NET 4.0

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string s = myFunction(PopulateTestList());
        this.TextBox1.Text = s;
    }

    protected List<int> PopulateTestList()
    {
        List<int> thisList = new List<int>();
        thisList.Add(22);
        thisList.Add(33);
        thisList.Add(44);

        return thisList;
    }

    protected string myFunction(List<int> a)
    {
        return string.Join(",", a);
    }
}

2

Trong .NET, lớp danh sách có một .ToArray()phương thức. Một cái gì đó như thế này có thể hoạt động:

string myFunction(List<int> a)
{
    return string.Join(",", a.ToArray());
}

Tham khảo: Danh sách các phương thức <T> (MSDN)


Điều này answer from 2010đã nói rằng, như ToStringđược ngụ ý khi thực hiện một string.Join.
Miller,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.