2009-12-03 13 views
15

Ho bisogno di dividere un array di dimensioni indeterminate, nel punto medio, in due array separati.C# Splitting An Array

La matrice viene generata da un elenco di stringhe utilizzando 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

Non esiste davvero una serie di dimensioni indeterminate. Se è un array, ha una proprietà Length. –

+1

la dimensione dell'array viene determinata in base al numero di variabili immesse dall'utente. Ho spiegato in alto. – TheValheruGod

+0

possibile duplicato di [Dividere una raccolta in n parti con LINQ?] (Http: // StackOverflow.it/questions/438188/split-a-collection-in-n-parts-with-linq) – nawfal

risposta

40

è possibile utilizzare il seguente metodo per dividere un array in 2 array separati

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

Grazie! Il secondo è perfetto! – TheValheruGod

+0

+1 per l'utilizzo dei metodi di estensione. –

+6

@Ian: quelli non sono metodi di estensione ... –

0

Perché non si assegnano due array e copiare il contenuto?

EDIT: qui si va:

 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

utilizzare un metodo di divisione generica:

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

Perché stai passando lo UList come riferimento? Non sembra esserci un bisogno per questo.

avrei usato un metodo generico Split se avevo bisogno di fare questo:

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

Ero solo io a giocare con il codice, è un residuo di alcune cose precedenti che erano lì dentro. – TheValheruGod

0

Penso che quello che stai cercando è la classe Array, in particolare il metodo statico Array.Copy. Si può pensare a quella classe come contenente i metodi che sarebbero metodi di istanza degli array se gli array C# avevano metodi.

1

Se non si dispone di LINQ, è possibile utilizzare 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

voglio anche aggiungere una soluzione di dividere un array in più array più piccoli dotati di un determinato numero di cellule.

Un buon modo sarebbe quello di creare un metodo generico/di estensione per dividere qualsiasi array. Questo è mio:

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

Inoltre, questa soluzione è differito. Quindi, chiama semplicemente split(size) sul tuo array.

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

Buon divertimento :)

0

questo è quello che mi serve

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

Perché è diverso? pensi che questo sia più efficiente delle altre soluzioni presentate in altre risposte? –

3

ho avuto un problema con di Linq Skip() e prendere() funzioni quando si tratta di array con enormi quantità di elementi (es. matrici di byte), dove i conteggi degli elementi sono in milioni.

Questo approccio ha ridotto drasticamente i tempi di esecuzione divisi.

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