2009-12-03 13 views
15

Potrzebuję podzielić tablicę o nieokreślonej wielkości, w punkcie środkowym, na dwie oddzielne tablice.C# Dzielenie tablicy

Tablica jest generowana z listy łańcuchów przy użyciu funkcji 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

Nie ma czegoś takiego jak tablica o nieokreślonej wielkości. Jeśli jest to tablica, ma właściwość Length. –

+1

Rozmiar tablicy jest określany w zależności od liczby zmiennych wprowadzanych przez użytkownika. Wyjaśniłem na górze. – TheValheruGod

+0

możliwy duplikat [Podziel kolekcję na n części z LINQ?] (Http: // stackoverflow.com/questions/438188/split-a-collection-to-n-parts-with-linq) – nawfal

Odpowiedz

40

Można użyć następującej metody podzielić tablicę w 2 oddzielnych tablic

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

Dziękujemy! Drugi jest doskonały! – TheValheruGod

+0

+1 za korzystanie z metod rozszerzeń. –

+6

@Ian: To nie są metody rozszerzeń ... –

0

Dlaczego nie przeznaczyć dwie tablice i skopiować zawartość?

EDIT: tutaj przejść:

 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

użyć metoda rodzajowa dzielone: ​​

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

Dlaczego mijasz UList jako ref? Wydaje się, że nie ma takiej potrzeby.

użyłbym rodzajowe Split metodę gdybym musiał to zrobić:

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

To tylko ja bawiłem się kodem, to pozostałość po wcześniejszych rzeczach, które tam były. – TheValheruGod

0

myślę co szukasz jest klasa Array konkretnie metoda statyczna Array.Copy. Możesz myśleć o tej klasie jako zawierającej metody, które byłyby metodami instancji tablic, gdyby tablice C# posiadały metody.

1

Jeśli nie masz Linq, można użyć 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

Chcę też dodać roztwór podzielić tablicę na kilka mniejszych tablic zawierających określoną liczbę komórek.

Dobrym sposobem byłoby stworzenie ogólnej/rozszerzającej metody dzielenia dowolnej tablicy. To jest moje:

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

Co więcej, to rozwiązanie jest odłożone. Następnie po prostu zadzwoń pod numer split(size) w swojej tablicy.

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

Have fun :)

0

to co muszę

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

Dlaczego jest inaczej? czy uważasz, że jest to skuteczniejsze niż inne rozwiązania przedstawione w innych odpowiedziach? –

3

miałem problem z LINQ za SKIP() i Take() funkcji, gdy ma do czynienia z tablicami z ogromnej ilości elementów (np. tablice bajtów), gdzie liczba elementów jest w milionach.

To podejście drastycznie zmniejszyło dla mnie czasy podziału czasu wykonania.

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