2008-10-03 20 views
14

¿Cuál es el enfoque de programación funcional para convertir un IEnumerable<string> en una cadena delimitada? Sé que puedo usar un bucle, pero estoy tratando de entender mi programación funcional.C# - IEnumerable a cadena delimitada

Aquí está mi ejemplo:

var selectedValues = 
from ListItem item in checkboxList.Items 
where item.Selected 
select item.Value; 

var delimitedString = ?? 

.. o podría hacer esto en tan sólo la primera asignación var (se añade a cada resultado a la anterior)?

Respuesta

17
var delimitedString = selectedValues.Aggregate((x,y) => x + ", " + y); 
+6

Eso será muy costoso en términos de cadenas intermedias. Muy FP, pero no muy práctico. http://www.yoda.arachsys.com/csharp/stringbuilder.html –

+4

@Marc, respondí la pregunta, se trataba de FP, no de rendimiento. –

31
string.Join(", ", string[] enumerable) 
+2

+1, pero yo diría que string.join ("", selectedValues.ToArray()) – Lucas

+2

@Lucas, no si está utilizando .NET 4. http://msdn.microsoft.com/en-us/library/dd992421.aspx –

+0

@Omer, cierto! pero esto fue en octubre de 2008, antes de .NET 4 :) – Lucas

4
var delimitedString = string.Join(",", checkboxList.Items.Where(i => i.Selected).Select(i => i.Value).ToArray()); 
2

Pues bien, en este caso el enfoque funcional podría no ser el más adecuado, simplemente porque no hay una LINQ "ParaCada", y usted no desea utilizar la concatenación de cadenas: desea usa StringBuilder. Se podría utilizar ToArray (un ejemplo acaba de aparecer más arriba), pero me gustaría tener la tentación de utilizar simplemente:

StringBuilder sb = new StringBuilder(); 
    foreach(ListViewItem item in checkboxList.SelectedItems) { 
     if(sb.Length > 0) sb.Append(','); 
     sb.Append(item.Text); 
    } 
    string s = sb.ToString(); 

No es la programación funcional, pero funciona ... por supuesto, si su fuente es ya una string [] then string.Join es perfecto. (LINQ es una gran herramienta, pero no siempre son la mejor herramienta para cada trabajo)

1

Aquí está una manera LINQ/funcional de hacerlo.


string[] toDelimit = CallSomeFunction(); 
return toDelimit.Aggregate((x, y) => x + "," + y); 
3

AviewAnew es la mejor respuesta, pero si lo que se busca es aprender a pensar en funcional, lo que debe hacer es utilizar una operación de pliegue (o agregarse como se le llama en NET).

items.Aggregate((accum, elem) => accum + ", " + elem); 
+0

¿El string.join es mejor por motivos de rendimiento? Diría que es mejor desde el punto de vista de la legibilidad. – Jeremy

+0

Yo diría que sí; .ToArray() [para obtener la cadena []] utilizará el doblaje, por lo que no hay muchas matrices intermedias, y luego string.Join es esencialmente StringBuilder; sin embargo, la concatenación de cuerdas tendrá una nueva cuerda cada vez, por lo que se ampliará en tamaño. –

+0

De acuerdo, este es el tipo de solución que encontraría en un lenguaje de programación funcional (como haskell), pero no aquí. Pero agarrar foldr es una de las claves para dominar los lenguajes funcionales. –

23

Aquí hay un ejemplo con un StringBuilder. Lo bueno es que Append() devuelve la instancia StringBuilder.

return list.Aggregate(new StringBuilder(), 
           (sb, s) => 
           (sb.Length == 0 ? sb : sb.Append(',')).Append(s)); 
+0

la última línea probablemente sea (sb.Length == 0? Sb.Append (s): sb.Append (',')) .Append (s)); – Tormod

0

Esto es compatible 3.5:

var selectedValues = String.Join(",", (from ListItem item in checkboxList.Items where item.Selected select item.Value).ToArray()); 
Cuestiones relacionadas