with strings separated example concatenate array c# string

strings - string join array c#



Crear una lista separada por comas desde IList<string> o IEnumerable<string> (21)

Acabo de resolver este problema antes de pasar a través de este artículo. Mi solución es algo como a continuación:

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

Llamado como

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); }

También podría haber expresado con tanta facilidad como tal y habría sido más eficiente:

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

¿Cuál es la forma más sencilla de crear una lista de valores de cadena separados por comas a partir de una IList<string> o IEnumerable<string> IList<string> ?

String.Join(...) opera en una string[] por lo que puede ser complicado trabajar cuando tipos como IList<string> o IEnumerable<string> no se pueden convertir fácilmente en una matriz de cadenas.


Algo un poco feo, pero funciona:

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

Le da un CSV de una Lista después de que le haya dado el convertidor (en este caso d => d.DivisionID.ToString ("b")).

Hacky pero funciona, ¿podría convertirse en un método de extensión tal vez?


Aquí hay otro método de extensión:

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


Así es como lo hice, usando la forma en que lo he hecho en otros idiomas:

private string ToStringList<T>(IEnumerable<T> list, string delimiter) { var sb = new StringBuilder(); string separator = String.Empty; foreach (T value in list) { sb.Append(separator).Append(value); separator = delimiter; } return sb.ToString(); }


Comencé esta discusión mientras buscaba un buen método de C # para unir cadenas, como se hace con el método MySQL CONCAT_WS() . Este método difiere del método string.Join() en que no agrega el signo separador si las cadenas son NULL o están vacías.

CONCAT_WS ('','', tbl.Lastname, tbl.Firstname)

solo devolverá el apellido si el primer nombre está vacío, mientras que

string.Join (",", strLastname, strFirstname)

devolverá strLastname + ", " en el mismo caso.

Queriendo el primer comportamiento, escribí los siguientes métodos:

public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string strA, string strB, string strC = "") { return JoinStringsIfNotNullOrEmpty(strSeparator, new[] {strA, strB, strC}); } public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string[] arrayStrings) { if (strSeparator == null) strSeparator = ""; if (arrayStrings == null) return ""; string strRetVal = arrayStrings.Where(str => !string.IsNullOrEmpty(str)).Aggregate("", (current, str) => current + (str + strSeparator)); int trimEndStartIndex = strRetVal.Length - strSeparator.Length; if (trimEndStartIndex>0) strRetVal = strRetVal.Remove(trimEndStartIndex); return strRetVal; }


Comparando por rendimiento, el ganador es "Loopear, Unirlo y hacer un paso atrás". En realidad, "siguiente y enumeración manual" es lo mismo bueno (considere 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 |

Código:

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 se utilizó


Creo que la forma más sencilla de crear una lista de valores de cadena separados por comas es simplemente:

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

Aquí hay un ejemplo completo:

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

No es necesario realizar una función auxiliar, esto está integrado en .NET 4.0 y superior.


Desde que llegué aquí mientras buscaba unirme a una propiedad específica de una lista de objetos (y no a ToString () de ella), aquí hay una adición a la respuesta aceptada:

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


Escribí algunos métodos de extensión para hacerlo de manera eficiente:

public static string JoinWithDelimiter(this IEnumerable<String> that, string delim) { var sb = new StringBuilder(); foreach (var s in that) { sb.AppendToList(s,delim); } return sb.ToString(); }

Esto depende de

public static string AppendToList(this String s, string item, string delim) { if (s.Length == 0) { return item; } return s+delim+item; }


Esperemos que esta sea la forma más sencilla.

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


La forma más fácil que puedo ver para hacer esto es usar el método de Aggregate LINQ:

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


Llegar un poco tarde a esta discusión pero esta es mi contribución fwiw. Tengo un IList<Guid> OrderIds de IList<Guid> OrderIds para convertir en una cadena CSV pero a continuación es genérico y funciona sin modificaciones con otros tipos:

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

Corto y dulce, usa StringBuilder para construir una nueva cadena, reduce la longitud de StringBuilder en uno para eliminar la última coma y devuelve la cadena CSV.

He actualizado esto para usar múltiples Append() ''s para agregar cadena + coma. De los comentarios de James, utilicé Reflector para echar un vistazo a StringBuilder.AppendFormat() . Resulta que AppendFormat() utiliza un StringBuilder para construir la cadena de formato, lo que lo hace menos eficiente en este contexto que el simple uso de múltiples Appends() .


Mi respuesta es como la de la solución Agregada anterior, pero debería tener menos volumen de pila de llamadas ya que no hay llamadas delegadas explícitas:

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(); }

Por supuesto, uno puede extender la firma para que sea independiente del delimitador. Realmente no soy un fanático de la llamada sb.Remove () y me gustaría refactorizarlo para que sea un bucle directo en un IEnumerable y usar MoveNext () para determinar si escribir o no una coma. Voy a juguetear y publicar esa solución si la encuentro.

Esto es lo que quería inicialmente:

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(); }

No se requiere almacenamiento temporal de matriz o lista, ni StringBuilder Remove() o Length-- requiere hackeo.

En mi biblioteca de marcos realicé algunas variaciones en esta firma de método, cada combinación de incluir el delimiter y los parámetros del converter con el uso de "," y x.ToString() como valores predeterminados, respectivamente.


Necesidad específica cuando deberíamos rodear por '', por ej:

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()));


Para su información, la versión .NET 4.0 de string.Join() tiene algunas sobrecargas adicionales , que funcionan con IEnumerable lugar de solo arreglos, incluido uno que puede tratar con cualquier tipo T :

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


Puede usar .ToArray() en Lists y IEnumerables , y luego usar String.Join() como desee.


Se pueden convertir fácilmente en una matriz utilizando las extensiones Linq en .NET 3.5.

var stringArray = stringList.ToArray();


También puede usar algo como lo siguiente después de convertirlo a una matriz usando uno de los métodos enumerados por otros:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Configuration; namespace ConsoleApplication { class Program { static void Main(string[] args) { CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection(); string[] itemList = { "Test1", "Test2", "Test3" }; commaStr.AddRange(itemList); Console.WriteLine(commaStr.ToString()); //Outputs Test1,Test2,Test3 Console.ReadLine(); } } }

Edit: Here hay otro ejemplo.


Tenemos una función de utilidad, algo como esto:

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

Que se puede usar para unir muchas colecciones fácilmente:

int[] ids = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233}; string csv = StringUtility.Join(",", ids, i => i.ToString() );

Tenga en cuenta que tenemos el parámetro de colección antes de la lambda porque intellisense luego recoge el tipo de colección.

Si ya tiene una enumeración de cadenas, todo lo que debe hacer es ToArray:

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


puede convertir el IList a una matriz utilizando ToArray y luego ejecutar un comando string.join en la matriz.

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


.NET 4+

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

Detalle y Pre .Net 4.0 Soluciones

IEnumerable<string> se puede convertir en una matriz de cadena muy fácilmente con LINQ (.NET 3.5):

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

Es bastante fácil escribir el método de ayuda equivalente si necesitas:

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

Entonces llámalo así:

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

A continuación, puede llamar a string.Join . Por supuesto, no tienes que usar un método de ayuda:

// 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());

Este último es un poco de un bocado aunque :)

Es probable que esta sea la forma más sencilla de hacerlo y que tenga un buen rendimiento también. Hay otras preguntas sobre cómo es exactamente el rendimiento, incluida (pero no limitada a) esta .

A partir de .NET 4.0, hay más sobrecargas disponibles en string.Join , así que puedes escribir:

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

Mucho más simple :)