2009-12-03 21 views
15

Necesito dividir una matriz de tamaño indeterminado, en el punto medio, en dos matrices separadas.C# Splitting An Array

La matriz se genera a partir de una lista de cadenas que utiliza ToArray().

 public void AddToList() 
     { 
      bool loop = true; 
      string a = ""; 

      Console.WriteLine("Enter a string value and press enter to add it to the list"); 
      while (loop == true) 
      { 
       a = Console.ReadLine(); 

       if (a != "") 
       { 
        mylist.Add(a); 
       } 
       else 
       { 
        loop = false; 
       } 
      } 

     } 

     public void ReturnList() 
     { 
      string x = ""; 
      foreach (string number in mylist) 
      { 
       x = x + number + " "; 
      } 
      Console.WriteLine(x); 
      Console.ReadLine(); 
     } 

    } 

    class SplitList 
    { 
     public string[] sTop; 
     public string[] sBottom; 

     public void Split(ref UList list) 
     { 
      string[] s = list.mylist.ToArray(); 

      //split the array into top and bottom halfs 

     } 
    } 

    static void Main(string[] args) 
    { 
     UList list = new UList(); 
     SplitList split = new SplitList(); 

     list.AddToList(); 
     list.ReturnList(); 

     split.Split(ref list); 
    } 
} 

}

+3

Realmente no existe una matriz de tamaño indeterminado. Si se trata de una matriz, tiene una propiedad de longitud. –

+1

el tamaño de la matriz se determina según la cantidad de variables introducidas por el usuario. Expliqué en la parte superior. – TheValheruGod

+0

posible duplicado de [¿Dividir una colección en n partes con LINQ?] (Http: // stackoverflow.com/questions/438188/split-a-collection-into-n-parts-with-linq) – nawfal

Respuesta

40

se puede utilizar el siguiente método para dividir una matriz en 2 matrices independientes

public void Split<T>(T[] array, int index, out T[] first, out T[] second) { 
    first = array.Take(index).ToArray(); 
    second = array.Skip(index).ToArray(); 
} 

public void SplitMidPoint<T>(T[] array, out T[] first, out T[] second) { 
    Split(array, array.Length/2, out first, out second); 
} 
+0

¡Gracias! ¡El segundo es perfecto! – TheValheruGod

+0

+1 para usar métodos de extensión. –

+6

@Ian: Esos no son métodos de extensión ... –

0

¿Por qué no se puede asignar dos matrices y copiar el contenido?

EDIT: Aquí van:

 String[] origin = new String[4]; 
     origin[0] = "zero"; 
     origin[1] = "one"; 
     origin[2] = "two"; 
     origin[3] = "three"; 

     Int32 topSize = origin.Length/2; 
     Int32 bottomSize = origin.Length - topSize; 
     String[] sTop = new String[topSize]; 
     String[] sBottom = new String[bottomSize]; 
     Array.Copy(origin, sTop, topSize); 
     Array.Copy(origin, topSize , sBottom, 0, bottomSize); 
7

utilizar un método de división genérica:

public static void Split<T>(T[] source, int index, out T[] first, out T last) 
{ 
    int len2 = source.Length - index; 
    first = new T[index]; 
    last = new T[len2]; 
    Array.Copy(source, 0, first, 0, index); 
    Array.Copy(source, index, last, 0, len2); 
} 
0

¿Por qué está pasando el UList como ref? No parece ser necesario para eso.

me gustaría utilizar un método genérico Split si necesitaba hacer esto:

public void Split<T>(T[] array, out T[] left, out T[] right) 
{ 
    left = new T[array.Length/2]; 
    right = new T[array.Length - left.Length]; 

    Array.Copy(array, left, left.Length); 
    Array.Copy(array, left.Length, right, 0, right.Length); 
} 
+0

Eso fue solo yo jugando con el código, es un recordatorio de algunas cosas anteriores que estaban allí. – TheValheruGod

0

creo que lo que estás buscando es la clase Array, específicamente el método estático Array.Copy. Puede pensar que esa clase contiene los métodos que serían métodos de instancia de matrices si las matrices C# tuvieran métodos.

1

Si usted no tiene LINQ, puede utilizar Array.Copy:

public void Split(ref UList list) 
{ 
    string[] s = list.mylist.ToArray(); 

    //split the array into top and bottom halfs 
    string[] top = new string[s.Length/2]; 
    string[] bottom = new string[s.Length - s.Length/2]; 
    Array.Copy(s, top, top.Length); 
    Array.Copy(s, top.Length, bottom, 0, bottom.Length); 

    Console.WriteLine("Top: "); 
    foreach (string item in top) Console.WriteLine(item); 
    Console.WriteLine("Bottom: "); 
    foreach (string item in bottom) Console.WriteLine(item); 
} 
5

También quiero añadir una solución para dividir una matriz en varias matrices más pequeñas que contienen un número determinado de células.

Una buena manera sería crear un método genérico/de extensión para dividir cualquier matriz. Esto es mío:

/// <summary> 
/// Splits an array into several smaller arrays. 
/// </summary> 
/// <typeparam name="T">The type of the array.</typeparam> 
/// <param name="array">The array to split.</param> 
/// <param name="size">The size of the smaller arrays.</param> 
/// <returns>An array containing smaller arrays.</returns> 
public static IEnumerable<IEnumerable<T>> Split<T>(this T[] array, int size) 
{ 
    for (var i = 0; i < (float)array.Length/size; i++) 
    { 
     yield return array.Skip(i * size).Take(size); 
    } 
} 

Además, esta solución se aplazó. Luego, simplemente llame al split(size) en su matriz.

var array = new byte[] {10, 20, 30, 40, 50}; 
var splitArray = array.Split(2); 

Diviértase :)

0

esto es lo que necesito

PartItemCount = Math.Max(PartItemCount , 1); 
lstlst = new List<List<T>>(); 

for (; lst.Count > 0 ;) 
{ 
    int partCount = Math.Min(lst.Count , PartItemCount); 
    List<T> lsttmp = new List<T>(lst.Take(partCount).ToArray()); 
    lstlst.Add(lsttmp); 
    lst = lst.Skip(partCount).ToList(); 
} 
return lstlst.Count; 
+0

¿Por qué es esto diferente? ¿Crees que esto es más eficiente que las otras soluciones presentadas en otras respuestas? –

3

tuve un problema con de LINQ Skip() y Take() funciona cuando se trata de matrices con grandes cantidades de elementos (es decir, matrices de bytes), donde los recuentos de elementos están en millones.

Este enfoque redujo drásticamente los tiempos de ejecución de división para mí.

public static IEnumerable<IEnumerable<T>> Split<T>(this ICollection<T> self, int chunkSize) 
{ 
    var splitList = new List<List<T>>(); 
    var chunkCount = (int)Math.Ceiling((double)self.Count/(double)chunkSize); 

    for(int c = 0; c < chunkCount; c++) 
    { 
     var skip = c * chunkSize; 
     var take = skip + chunkSize; 
     var chunk = new List<T>(chunkSize); 

     for(int e = skip; e < take && e < self.Count; e++) 
     { 
      chunk.Add(self.ElementAt(e)); 
     } 

     splitList.Add(chunk); 
    } 

    return splitList; 
}