¿Cuál es la forma más eficiente de escribir la vieja escuela?
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
... en LINQ?
c#
linq
string-concatenation
etiquetas2k
fuente
fuente
Respuestas:
Esta respuesta muestra el uso de LINQ (
Aggregate
) según lo solicitado en la pregunta y no está destinado para el uso diario. Debido a que esto no usa unStringBuilder
, tendrá un rendimiento horrible para secuencias muy largas. Para el uso regular del códigoString.Join
como se muestra en la otra respuestaUse consultas agregadas como esta:
Esto produce:
Un agregado es una función que toma una colección de valores y devuelve un valor escalar. Los ejemplos de T-SQL incluyen min, max y sum. Tanto VB como C # tienen soporte para agregados. Tanto VB como C # admiten agregados como métodos de extensión. Usando la notación de puntos, uno simplemente llama a un método en un objeto IEnumerable .
Recuerde que las consultas agregadas se ejecutan de inmediato.
Más información - MSDN: consultas agregadas
Si realmente desea
Aggregate
utilizar la variante de usoStringBuilder
propuesta en el comentario de CodeMonkeyKing, que sería aproximadamente el mismo código que el habitual,String.Join
incluido un buen rendimiento para una gran cantidad de objetos:fuente
""
, el primer valor utilizadocurrent
es una cadena vacía. Entonces, para 1 o más elementos, siempre obtendrá,
al comienzo de la cadena.En .Net 4, hay una nueva sobrecarga para
string.Join
que acepteIEnumerable<string>
. El código se vería así:fuente
¿Por qué usar Linq?
Eso funciona perfectamente y acepta cualquiera
IEnumerable<string>
hasta donde recuerdo. No necesitaAggregate
nada aquí, que es mucho más lento.fuente
String.Join(",", s.ToArray())
en las versiones anteriores.¿Has mirado el método de extensión Agregado?
fuente
Ejemplo real de mi código:
Una consulta es un objeto que tiene una propiedad Name que es una cadena, y quiero los nombres de todas las consultas en la lista seleccionada, separadas por comas.
fuente
Aquí está el enfoque combinado Join / Linq que decidí después de mirar las otras respuestas y los problemas abordados en una pregunta similar (a saber, que Aggregate and Concatenate fallan con 0 elementos).
string Result = String.Join(",", split.Select(s => s.Name));
o (si
s
no es una cadena)string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
) para implementarY, por supuesto, Join se encarga de la molesta coma final que a veces se cuela en otros enfoques (
for
,foreach
), por lo que estaba buscando una solución de Linq en primer lugar.fuente
.Select()
este tipo proporciona un lugar fácil para modificar cada elemento durante esta operación. Por ejemplo, envolviendo cada elemento en algún personaje asístring Result = String.Join(",", split.Select(s => "'" + s + "'"));
Puedes usar
StringBuilder
enAggregate
:(El
Select
está ahí solo para mostrar que puedes hacer más cosas de LINQ).fuente
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
if (length > 0)
el linq y al sacarlo.new[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
Datos de rendimiento rápido para el caso StringBuilder vs Select & Aggregate sobre más de 3000 elementos:
Prueba unitaria - Duración (segundos)
LINQ_StringBuilder - 0.0036644
LINQ_Select.Aggregate - 1.8012535
fuente
Siempre uso el método de extensión:
fuente
string.Join
en .net 4 ya puede tomar unIEnumerable<T>
para cualquier arbitrarioT
.Con la 'manera súper genial de LINQ ', podría estar hablando de la forma en que LINQ hace que la programación funcional sea mucho más aceptable con el uso de métodos de extensión. Quiero decir, el azúcar sintáctico que permite encadenar funciones de una manera visualmente lineal (una después de la otra) en lugar de anidar (una dentro de la otra). Por ejemplo:
se puede escribir así:
Puede ver cómo el segundo ejemplo es más fácil de leer. También puede ver cómo se pueden agregar más funciones con menos problemas de sangría o los pares de cierre de Lispy que aparecen al final de la expresión.
Muchas de las otras respuestas indican que este
String.Join
es el camino a seguir porque es el más rápido o el más simple de leer. Pero si toma mi interpretación de la ' forma LINQ súper genial ', entonces la respuesta es usar,String.Join
pero envuélvala en un método de extensión de estilo LINQ que le permitirá encadenar sus funciones de una manera visualmente agradable. Entonces, si quieres escribirsa.Concatenate(", ")
, solo necesitas crear algo como esto:Esto proporcionará un código que es tan eficaz como la llamada directa (al menos en términos de complejidad del algoritmo) y en algunos casos puede hacer que el código sea más legible (según el contexto), especialmente si otro código en el bloque está usando el estilo de función encadenada .
fuente
Hay varias respuestas alternativas en esta pregunta anterior , que ciertamente apuntaba a una matriz entera como fuente, pero recibió respuestas generalizadas.
fuente
Aquí está usando LINQ puro como una sola expresión:
¡Y es bastante rápido!
fuente
Voy a hacer un poco de trampa y arrojar una nueva respuesta a esto que parece resumir lo mejor de todo aquí en lugar de incluirlo en un comentario.
Entonces puedes una línea de esto:
Editar: primero querrá verificar si hay un enumerable vacío o agregar un
.Replace("\a",string.Empty);
al final de la expresión. Supongo que podría haber estado tratando de ser demasiado inteligente.La respuesta de @ a.friend podría ser un poco más eficaz, no estoy seguro de lo que Reemplazar hace bajo el capó en comparación con Eliminar. La única otra advertencia es que si por alguna razón quisieras concatenar cadenas que terminaran en \ a, perderías tus separadores ... Me parece poco probable. Si ese es el caso, tiene otros personajes elegantes para elegir.
fuente
Puede combinar LINQ y con
string.join()
bastante eficacia. Aquí estoy eliminando un elemento de una cadena. También hay mejores formas de hacerlo, pero aquí está:fuente
Muchas opciones aquí. Puede usar LINQ y un StringBuilder para obtener el rendimiento de la siguiente manera:
fuente
builder.Length > 0
ForEach y eliminar la primera coma después de ForEachHice lo siguiente rápido y sucio cuando analicé un archivo de registro IIS usando linq, funcionó a 1 millón de líneas bastante bien (15 segundos), aunque obtuvo un error de falta de memoria al intentar 2 millones de líneas.
La verdadera razón por la que usé linq fue por un Distinct () que necesitaba anteriormente:
fuente
Hace un blog escribí sobre esto hace un tiempo, lo que hice parece ser exactamente lo que estás buscando:
http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html
En la publicación del blog describa cómo implementar métodos de extensión que funcionen en IEnumerable y se denominen Concatenate, esto le permitirá escribir cosas como:
O cosas más elaboradas como:
fuente