string.Unirse a una List <int> u otro tipo

86

Quiero convertir una matriz o lista de entradas en una cadena delimitada por comas, como esta:

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

Pero string.Join solo toma List<string>como segundo parámetro. ¿Cuál es la mejor manera de hacer esto?

Comandante de código
fuente
2
¿Qué versión de C # / .NET estás usando?
Mark Byers
Posible duplicado de stackoverflow.com/questions/3211422/…
goodeye

Respuestas:

149

La mejor manera es actualizar a .NET 4.0 donde hay una sobrecarga que hace lo que desea:

Si no puede actualizar, puede lograr el mismo efecto usando Select y ToArray.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());
Mark Byers
fuente
También se supone que está al menos en C # 3, .NET 3.5
Anthony Pegram
¿Por qué utilizar LINQ en lugar del ToArraymétodo integrado de List<T>?
Steven Sudit
2
porque tendría una List <int>. El linq select convierte List <int> a IEnumerable <string> y luego a la matriz.
Greg Bogumil
Actualizar a 4.0 no es práctico en mi situación, pero la solución LINQ es exactamente lo que estaba buscando. ¡Gracias!
Code Commander
1
@gbogumil: Lo siento, no me di cuenta de que era un int.
Steven Sudit
5

Una implementación escalable y segura de una combinación de cadena enumerable genérica para .NET 3.5. El uso de iteradores es para que el valor de la cadena de unión no se atasque al final de la cadena. Funciona correctamente con 0, 1 y más elementos:

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

Uso:

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

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

¡Disfrutar!

Eliminado
fuente
+1: Esta es mi forma preferida antes de .NET 4.0. Mucho más escalable que producir una matriz de cadenas completamente nueva a partir de una lista de entradas para que String.Join(String, String[])se pueda llamar. Lo único que diría es que es inusual ver este método escrito como una extensión en Stringlugar de IEnumerable<String>: tiendo a llamarlo siempre al final de una larga cadena de llamadas al método de extensión.
Alex Humphrey
2
¡Le robé la idea a Python si eso me ayuda!
Eliminado el
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();
}
Kyle Rosendo
fuente
3
Un buen enfoque 2.0. Es posible que desee convertir el carácter de unión en un parámetro en lugar de codificarlo en el método.
Anthony Pegram
Una optimización típica es agregar el delimitador sin probar, luego eliminar el último carácter una vez que salga del ciclo.
Steven Sudit
@Steven: estaba pensando en ello, pero creo que esto también dependería de la longitud de la cadena (sin probar, no estoy seguro), así que me limité a la simple verificación bool.
Kyle Rosendo
Sospecho que la optimización solo sería medible para cadenas largas. Habiendo dicho eso, no creo que sea más lento ni siquiera para los cortos.
Steven Sudit
3

Tenía un método de extensión similar que modifiqué a este

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

y lo usas así

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

.NET 3.5

Jonas Elfström
fuente
No estoy seguro de que me guste esto. IEnumerable<T>ya tiene un Joinmétodo, y este nuevo método realiza una operación completamente diferente, lo que hace que su uso sea contradictorio. En segundo lugar, si estabas va a crear este método, seguir adelante y hacer que sea genéricamente aplicable.
Anthony Pegram
Es un truco que imita el método de unión en matrices en Ruby. ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström
Además .ToString () no siempre devuelve una representación de cadena de T, así que supongo que eso realmente podría causar cierta confusión.
Jonas Elfström
2

Esta respuesta es para usted si todavía no desea aventurarse en las profundidades de .NET 4.0.

String.Join () concatena todos los elementos de una matriz de cadenas, utilizando el separador especificado entre cada elemento.

La sintaxis es

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

En lugar de pasar su Lista de entradas al método Join, sugiero que primero cree una matriz de cadenas.

Esto es lo que propongo:

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);
}
Greg
fuente
3
Este es un enfoque decente si alguien todavía está en 2.0. Sin embargo, intArrayes innecesario. List<int>es indexable y tiene una Countpropiedad, por lo que la conversión a una matriz es superflua. También es posible que desee convertir el carácter de unión en un parámetro en lugar de codificarlo en el método.
Anthony Pegram
2

Usando .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);
    }
}
user436001
fuente
2

En .NET, la clase list tiene un .ToArray()método. Algo como esto podría funcionar:

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

Ref: Métodos List <T> (MSDN)

wintoch
fuente
Esto answer from 2010ya establece que, como ToStringse implica al hacer un string.Join.
Miller