2012-05-22 231 views
12

Edición: He probado el método de Take/Skip pero me sale el siguiente error:Dividir un array en 2 arrays de C#

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 
'string[]'. An explicit conversion exists (are you missing a cast?) 

no sé lo que estoy haciendo mal, porque he copiado Saeed código.

Tengo una matriz de cadenas (que contiene entre 20 y 300 elementos) y quiero dividirla en 2 matrices separadas, desde la mitad de la primera.

Sé cómo puedo hacer esto usando un ciclo for pero me gustaría saber si hubo una forma más rápida/mejor de hacerlo. También tengo que ser capaz de dividir correctamente una gama aún más si se tiene un número impar de elementos, por ejemplo:

string[] words = {"apple", "orange", "banana", "pear", "lemon"}; 
string[] firstarray, secondarray; 
SplitArray(words, out firstarray, out secondarray); // Or some other function 
// firstarray has the first 3 of the items from words, 'apple', 'orange' and 'banana' 
// secondarray has the other 2, 'pear' and 'lemon' 
+0

Con el fin de resolver su problema fundido añadir '.ToArray()' después de la toma y por omitir métodos –

Respuesta

38

Puede utilizar LINQ:

firstArray = array.Take(array.Length/2).ToArray(); 
secondArray = array.Skip(array.Length/2).ToArray(); 

Por qué esto funciona, a pesar de la paridad de el tamaño original de la matriz?

El primer Array toma array.Length/2 elementos, y el segundo se salta los primeros elementos array.Length/2, significa que no hay ningún conflicto entre estos dos arreglos. Por supuesto, si la cantidad de elementos es impar, no podemos dividir la matriz en dos partes de igual tamaño.

Si usted quiere tener más elementos en la primera mitad (en algún caso), hacer esto:

firstArray = array.Take((array.Length + 1)/2).ToArray(); 
secondArray = array.Skip((array.Length + 1)/2).ToArray(); 
+0

Gracias, lo intentaremos pronto, pero ¿manejará esto la división correctamente incluso si tiene un número impar de elementos? – 3aw5TZetdf

+0

@MatthewRz, Sí, siempre funciona bien. –

+0

Muy bien, ¡muchas gracias! – 3aw5TZetdf

4
string[] words = {"apple", "orange", "banana", "pear", "lemon"}; 
int mid = words.Length/2; 
string[] first = words.Take(mid).ToArray(); 
string[] second = words.Skip(mid).ToArray(); 
+0

¡Gracias! Voy a intentar esto pronto. – 3aw5TZetdf

2
string[] words = { "apple", "orange", "banana", "pear", "lemon" }; 
var halfWay = words.Length/2; 

var firstHalf = words.Take(halfWay); 
var secondHalf = words.Skip(halfWay); 
3

Un enfoque más generalizado que lo dividirá en tantas partes como se especifica:

public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts) 
     { 
      return list.Select((item, index) => new {index, item}) 
         .GroupBy(x => (x.index + 1)/(list.Count()/parts) + 1) 
         .Select(x => x.Select(y => y.item)); 
     } 

* Editado, gracias skarmats

+2

Esto cambiará el orden de las cosas. Entonces, la enésima matriz resultante no se corresponderá con la enésima sección de la fuente. – skarmats

+0

Actualizado para evitar la formación de rayas en la matriz. – Totero

4

Si no quiere/no se puede utilizar LINQ puede simplemente hacer:

string[] words = { "apple", "orange", "banana", "pear", "lemon" }; 
    string[] firstarray, secondarray; 
    int mid = words.Length/2; 
    firstarray = new string[mid]; 
    secondarray = new string[words.Length - mid]; 
    Array.Copy(words, 0, firstarray, 0, mid); 
    Array.Copy(words, mid, secondarray, 0, secondarray.Length);