c# c#字串分割字串 - 從IList<string>或IEnumerable<string>創建逗號分隔列表




c#數字切割 replace用法 (18)

希望這是最簡單的方法

 string Commaseplist;
 string[] itemList = { "Test1", "Test2", "Test3" };
 Commaseplist = string.join(",",itemList);
 Console.WriteLine(Commaseplist); //Outputs Test1,Test2,Test3

IList<string>IEnumerable<string>創建逗號分隔的字符串值列表的最簡單方法是什麼?

String.Join(...)string[]操作,因此當IList<string>IEnumerable<string>無法輕易轉換為字符串數組時,可能會很麻煩。


我能看到的最簡單的方法是使用LINQ Aggregate方法:

string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)

我認為創建一個以逗號分隔的字符串值列表的最簡潔的方法很簡單:

string.Join<string>(",", stringEnumerable);

這裡是一個完整的例子:

IEnumerable<string> stringEnumerable= new List<string>();
stringList.Add("Comma");
stringList.Add("Separated");

string.Join<string>(",", stringEnumerable);

沒有必要建立一個輔助函數,這是內置於.NET 4.0及以上的。


我們有一個實用功能,就像這樣:

public static string Join<T>( string delimiter, 
    IEnumerable<T> collection, Func<T, string> convert )
{
    return string.Join( delimiter, 
        collection.Select( convert ).ToArray() );
}

它可以用於輕鬆地連接大量的集合:

int[] ids = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233};

string csv = StringUtility.Join(",", ids, i => i.ToString() );

請注意,我們在lambda之前有集合參數,因為intellisense然後選取集合類型。

如果你已經有了一個字符串枚舉,你需要做的就是ToArray:

string csv = string.Join( ",", myStrings.ToArray() );

您可以使用ToArray將IList轉換為數組,然後在數組上運行string.join命令。

Dim strs As New List(Of String)
Dim arr As Array
arr = strs.ToArray

在本文中,我剛剛解決了這個問題。 我的解決方案如下所示:

   private static string GetSeparator<T>(IList<T> list, T item)
   {
       return (list.IndexOf(item) == list.Count - 1) ? "" : ", ";
   }

被稱為:

List<thing> myThings;
string tidyString;

foreach (var thing in myThings)
{
     tidyString += string.format("Thing {0} is a {1}", thing.id, thing.name) + GetSeparator(myThings, thing);
}

我也可以像這樣容易地表達,並且也會更有效率:

string.Join(“,”, myThings.Select(t => string.format(“Thing {0} is a {1}”, t.id, t.name)); 

有些東西有點難看,但它起作用:

string divisionsCSV = String.Join(",", ((List<IDivisionView>)divisions).ConvertAll<string>(d => d.DivisionID.ToString("b")).ToArray());

在給它一個轉換器(在這種情況下,d => d.DivisionID.ToString(“b”))後,從列表中為您提供一個CSV。

哈克但是作品 - 可能會變成擴展方法嗎?


.NET 4+

IList<string> strings = new List<string>{"1","2","testing"};
string joined = string.Join(",", strings);

Detail&Pre .Net 4.0解決方案

使用LINQ(.NET 3.5)可以非常輕鬆地將IEnumerable<string>轉換為字符串數組:

IEnumerable<string> strings = ...;
string[] array = strings.ToArray();

如果您需要:編寫等效的幫助器方法很容易:

public static T[] ToArray(IEnumerable<T> source)
{
    return new List<T>(source).ToArray();
}

然後像這樣調用它:

IEnumerable<string> strings = ...;
string[] array = Helpers.ToArray(strings);

然後你可以調用string.Join 。 當然,你不必使用輔助方法:

// C# 3 and .NET 3.5 way:
string joined = string.Join(",", strings.ToArray());
// C# 2 and .NET 2.0 way:
string joined = string.Join(",", new List<string>(strings).ToArray());

後者雖然有點滿口:)

這很可能是最簡單的方式,而且性能也很高 - 還有其他問題關於性能如何,包括(但不限於) 這個

從.NET 4.0開始, string.Join有更多的重載,所以你可以寫下:

string joined = string.Join(",", strings);

更簡單:)


稍後討論一下,但這是我的貢獻。 我有一個IList<Guid> OrderIds被轉換為一個CSV字符串,但以下是通用的,並且可以不加修改地與其他類型一起工作:

string csv = OrderIds.Aggregate(new StringBuilder(),
             (sb, v) => sb.Append(v).Append(","),
             sb => {if (0 < sb.Length) sb.Length--; return sb.ToString();});

簡短而親切,使用StringBuilder構建新字符串,將StringBuilder長度縮小一個以除去最後一個逗號並返回CSV字符串。

我更新了這個使用多個Append()來添加字符串+逗號。 從James的反饋中,我使用了Reflector來看看StringBuilder.AppendFormat() 。 原來AppendFormat()使用一個StringBuilder來構造格式化字符串,這使得它在這個上下文中效率低於僅僅使用多個Appends()


我的答案就像上面的Aggregate解決方案一樣,但由於沒有明確的委託調用,所以應該更少的調用堆棧:

public static string ToCommaDelimitedString<T>(this IEnumerable<T> items)
{
    StringBuilder sb = new StringBuilder();
    foreach (var item in items)
    {
        sb.Append(item.ToString());
        sb.Append(',');
    }
    if (sb.Length >= 1) sb.Length--;
    return sb.ToString();
}

當然,可以將簽名擴展為與分隔符無關。 我真的不是sb.Remove()調用的粉絲,我想將它重構為IEnumerable上的while循環,並使用MoveNext()來確定是否寫一個逗號。 如果我遇到它,我會小心翼翼地發布解決方案。

這是我最初想要的:

public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter, Func<T, string> converter)
{
    StringBuilder sb = new StringBuilder();
    var en = source.GetEnumerator();
    bool notdone = en.MoveNext();
    while (notdone)
    {
        sb.Append(converter(en.Current));
        notdone = en.MoveNext();
        if (notdone) sb.Append(delimiter);
    }
    return sb.ToString();
}

不需要臨時數組或列表存儲,也不需要StringBuilder Remove()Length-- hack。

在我的框架庫中,我對這個方法簽名做了一些修改,包括delimiterconverter參數的每個組合,分別使用","x.ToString()作為默認值。


可以使用.NET 3.5中的Linq擴展輕鬆地將它們轉換為數組。

   var stringArray = stringList.ToArray();

通過表現比較,獲勝者是“循環播放,加入併後退一步”。 其實“enumerable和手動移動”是一樣的好(考慮stddev)。

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Core   : .NET Core 4.6.25009.03, 64bit RyuJIT


                Method |  Job | Runtime |     Mean |     Error |    StdDev |      Min |      Max |   Median | Rank |  Gen 0 | Allocated |
---------------------- |----- |-------- |---------:|----------:|----------:|---------:|---------:|---------:|-----:|-------:|----------:|
            StringJoin |  Clr |     Clr | 28.24 us | 0.4381 us | 0.3659 us | 27.68 us | 29.10 us | 28.21 us |    8 | 4.9969 |   16.3 kB |
 SeparatorSubstitution |  Clr |     Clr | 17.90 us | 0.2900 us | 0.2712 us | 17.55 us | 18.37 us | 17.80 us |    6 | 4.9296 |  16.27 kB |
     SeparatorStepBack |  Clr |     Clr | 16.81 us | 0.1289 us | 0.1206 us | 16.64 us | 17.05 us | 16.81 us |    2 | 4.9459 |  16.27 kB |
            Enumerable |  Clr |     Clr | 17.27 us | 0.0736 us | 0.0615 us | 17.17 us | 17.36 us | 17.29 us |    4 | 4.9377 |  16.27 kB |
            StringJoin | Core |    Core | 27.51 us | 0.5340 us | 0.4995 us | 26.80 us | 28.25 us | 27.51 us |    7 | 5.0296 |  16.26 kB |
 SeparatorSubstitution | Core |    Core | 17.37 us | 0.1664 us | 0.1557 us | 17.15 us | 17.68 us | 17.39 us |    5 | 4.9622 |  16.22 kB |
     SeparatorStepBack | Core |    Core | 15.65 us | 0.1545 us | 0.1290 us | 15.45 us | 15.82 us | 15.66 us |    1 | 4.9622 |  16.22 kB |
            Enumerable | Core |    Core | 17.00 us | 0.0905 us | 0.0654 us | 16.93 us | 17.12 us | 16.98 us |    3 | 4.9622 |  16.22 kB |

碼:

public class BenchmarkStringUnion
{
    List<string> testData = new List<string>();
    public BenchmarkStringUnion()
    {
        for(int i=0;i<1000;i++)
        {
            testData.Add(i.ToString());
        }
    }
    [Benchmark]
    public string StringJoin()
    {
        var text = string.Join<string>(",", testData);
        return text;
    }
    [Benchmark]
    public string SeparatorSubstitution()
    {
        var sb = new StringBuilder();
        var separator = String.Empty;
        foreach (var value in testData)
        {
            sb.Append(separator).Append(value);
            separator = ",";
        }
        return sb.ToString();
    }

    [Benchmark]
    public string SeparatorStepBack()
    {
        var sb = new StringBuilder();
        foreach (var item in testData)
            sb.Append(item).Append(',');
        if (sb.Length>=1) 
            sb.Length--;
        return sb.ToString();
    }

    [Benchmark]
    public string Enumerable()
    {
        var sb = new StringBuilder();
        var e = testData.GetEnumerator();
        bool  moveNext = e.MoveNext();
        while (moveNext)
        {
            sb.Append(e.Current);
            moveNext = e.MoveNext();
            if (moveNext) 
                sb.Append(",");
        }
        return sb.ToString();
    }
}

https://github.com/dotnet/BenchmarkDotNet被使用


這是另一種擴展方法:

    public static string Join(this IEnumerable<string> source, string separator)
    {
        return string.Join(separator, source);
    }

您可以在ListsIEnumerables上使用.ToArray() ,然後根據需要使用String.Join()


僅供參考,.NET 4.0版本的string.Join()有一些額外的重載 ,它們與IEnumerable而不是數組一起工作,包括可以處理任何類型T

public static string Join(string separator, IEnumerable<string> values)
public static string Join<T>(string separator, IEnumerable<T> values)

由於我在搜索時加入了一個對象列表的特定屬性(而不是它的ToString()),因此我在這裡添加了接受的答案:

var commaDelimited = string.Join(",", students.Where(i => i.Category == studentCategory)
                                 .Select(i => i.FirstName));

具體需要什麼時候我們應該圍繞',由前:

        string[] arr = { "jj", "laa", "123" };
        List<string> myList = arr.ToList();

        // 'jj', 'laa', '123'
        Console.WriteLine(string.Join(", ",
            myList.ConvertAll(m =>
                string.Format("'{0}'", m)).ToArray()));

我喜歡的兩件事是自動屬性,所以你可以進一步折疊你的代碼:

private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

public string Name { get; set;}

還有對像初始化器:

Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();

Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}






c# string