recorrer multidimensional example array c# arrays string loops

multidimensional - C#: forma más limpia de dividir un conjunto de cadenas en N instancias N elementos largos



string array add c# (8)

Creo que esto es simple y rápido. El siguiente ejemplo divide la oración larga en 15 partes, pero puede pasar el tamaño del lote como parámetro para hacerlo dinámico. Aquí simplemente divido usando "/ n".

private static string Concatenated(string longsentence) { const int batchSize = 15; string concatanated = ""; int chanks = longsentence.Length / batchSize; int currentIndex = 0; while (chanks > 0) { var sub = longsentence.Substring(currentIndex, batchSize); concatanated += sub + "/n"; chanks -= 1; currentIndex += batchSize; } if (currentIndex < longsentence.Length) { int start = currentIndex; var finalsub = longsentence.Substring(start); concatanated += finalsub; } return concatanated; }

Este espectáculo es resultado de una operación dividida.

var parts = Concatenated(longsentence).Split(new string[] { "/n" }, StringSplitOptions.None);

Sé cómo hacer esto de una manera fea, pero me pregunto si hay un método más elegante y conciso.

Tengo una matriz de cadenas de direcciones de correo electrónico. Supongamos que el conjunto de cadenas tiene una longitud arbitraria: podría tener algunos elementos o podría tener muchos elementos. Quiero construir otra cadena que consta de, por ejemplo, 50 direcciones de correo electrónico de la matriz de cadenas, hasta el final de la matriz, e invocar una operación de envío después de cada 50, utilizando la cadena de 50 direcciones en el método Send ().

La pregunta más general es cuál es la forma más clara y clara de hacer este tipo de cosas. Tengo una solución que es un legado de mis conocimientos de VBScript, pero apuesto a que hay una mejor manera en C #.


Creo que necesitamos tener un poco más de contexto sobre cómo es exactamente esta lista para dar una respuesta definitiva. Por ahora, estoy asumiendo que es una lista de direcciones de correo electrónico con punto y coma. Si es así, puede hacer lo siguiente para obtener una lista fragmentada.

public IEnumerable<string> DivideEmailList(string list) { var last = 0; var cur = list.IndexOf('';''); while ( cur >= 0 ) { yield return list.SubString(last, cur-last); last = cur + 1; cur = list.IndexOf('';'', last); } } public IEnumerable<List<string>> ChunkEmails(string list) { using ( var e = DivideEmailList(list).GetEnumerator() ) { var list = new List<string>(); while ( e.MoveNext() ) { list.Add(e.Current); if ( list.Count == 50 ) { yield return list; list = new List<string>(); } } if ( list.Count != 0 ) { yield return list; } } }


Extensiones basadas en la respuesta de Eric :

public static IEnumerable<IEnumerable<T>> SplitIntoChunks<T>(this T[] source, int chunkSize) { var chunks = from index in Enumerable.Range(0, source.Length) group source[index] by index / chunkSize; return chunks; } public static T[][] SplitIntoArrayChunks<T>(this T[] source, int chunkSize) { var chunks = from index in Enumerable.Range(0, source.Length) group source[index] by index / chunkSize; return chunks.Select(e => e.ToArray()).ToArray(); }


Parece que la entrada consiste en cadenas de direcciones de correo electrónico separadas en una matriz grande, no varias direcciones de correo electrónico en una cadena, ¿verdad? Y en la salida, cada lote es una sola cadena combinada.

string[] allAddresses = GetLongArrayOfAddresses(); const int batchSize = 50; for (int n = 0; n < allAddresses.Length; n += batchSize) { string batch = string.Join(";", allAddresses, n, Math.Min(batchSize, allAddresses.Length - n)); // use batch somehow }


Parece similar a esta pregunta: ¿ dividir una colección en n partes con LINQ?

Una versión modificada de la respuesta de Hasan Khan debe hacer el truco:

public static IEnumerable<IEnumerable<T>> Chunk<T>( this IEnumerable<T> list, int chunkSize) { int i = 0; var chunks = from name in list group name by i++ / chunkSize into part select part.AsEnumerable(); return chunks; }

Ejemplo de uso:

var addresses = new[] { "[email protected]", "[email protected]", ...... }; foreach (var chunk in Chunk(addresses, 50)) { SendEmail(chunk.ToArray(), "Buy V14gr4"); }


Quieres elegante y conciso, te daré elegante y sucinto:

var fifties = from index in Enumerable.Range(0, addresses.Length) group addresses[index] by index/50; foreach(var fifty in fifties) Send(string.Join(";", fifty.ToArray());

¿Por qué perder el tiempo con todo ese espantoso código de bucle cuando no es necesario? Desea agrupar las cosas por cincuenta, luego agrúpelas por cincuenta. ¡Para eso es el operador del grupo!

ACTUALIZACIÓN: el comentarista MoreCoffee pregunta cómo funciona esto. Supongamos que queremos agrupar de a tres, porque es más fácil escribir.

var threes = from index in Enumerable.Range(0, addresses.Length) group addresses[index] by index/3;

Supongamos que hay nueve direcciones, indexadas de cero a ocho

¿Qué significa esta consulta?

Enumerable.Range es un rango de nueve números que comienzan en cero, por lo que 0, 1, 2, 3, 4, 5, 6, 7, 8 .

El index variable de rango toma cada uno de estos valores por turno.

Luego revisamos cada addresses[index] y la asignamos a un grupo.

¿A qué grupo lo asignamos? Para agrupar el index/3 . Rondas aritméticas enteras hacia cero en C #, por lo que los índices 0, 1 y 2 se convierten en 0 cuando se dividen en 3. Los índices 3, 4 y 5 se convierten en 1 cuando se dividen en 3. Los índices 6, 7 y 8 se convierten en 2.

Asignamos addresses[0] , addresses[1] y addresses[2] al grupo 0, addresses[3] , addresses[4] y addresses[5] al grupo 1, y así sucesivamente.

El resultado de la consulta es una secuencia de tres grupos, y cada grupo es una secuencia de tres elementos.

¿Tiene sentido?

Recuerde también que el resultado de la expresión de consulta es una consulta que representa esta operación . No realiza la operación hasta que se ejecuta el ciclo foreach .


Simplemente recorro el conjunto y uso StringBuilder para crear la lista (supongo que está separada por, como lo haría para el correo electrónico). Solo envíe cuando llegue al mod 50 o al final.

void Foo(string[] addresses) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < addresses.Length; i++) { sb.Append(addresses[i]); if ((i + 1) % 50 == 0 || i == addresses.Length - 1) { Send(sb.ToString()); sb = new StringBuilder(); } else { sb.Append("; "); } } } void Send(string addresses) { }


Suponiendo que está utilizando .NET 3.5 y C # 3, algo así debería funcionar bien:

string[] s = new string[] {"1", "2", "3", "4"....}; for (int i = 0; i < s.Count(); i = i + 50) { string s = string.Join(";", s.Skip(i).Take(50).ToArray()); DoSomething(s); }