2009-11-24 21 views
31

Se si dispone di un array con 12 elementi e voglio un nuovo array con quello elimina il primo e il dodicesimo elemento. Ad esempio, se la mia matrice è simile al seguente:Sottoinsieme di array in C#

__ __ __ __ __ __ __ __ __ __ __ __ 
a b c d e f g h i j k l 
__ __ __ __ __ __ __ __ __ __ __ __ 

voglio né trasformarlo o creare un nuovo array che assomiglia

__ __ __ __ __ __ __ __ __ __ 

b c d e f g h i j k 
__ __ __ __ __ __ __ __ __ __ 

so che posso farlo mediante iterazione su di loro. Mi stavo chiedendo se c'era un modo più pulito integrato in C#.

** AGGIORNATO PER FISSARE UN TIPO. Cambiato 10 elementi in 12 elementi.

+0

Non è "j" il decimo elemento nell'array? O intendevi il primo e l'ultimo elemento? –

risposta

66

LINQ è tuo amico. :)

var newArray = oldArray.Skip(1).Take(oldArray.Length - 2).ToArray(); 

meno efficiente rispetto alla creazione manualmente matrice e iterando su di esso naturalmente, ma molto semplice ...

Il metodo leggermente lengithier che utilizza Array.Copy è il seguente.

var newArray = new int[newArray.Count - 2]; 
Array.Copy(oldArray, 1, newArray, 0, newArray.Length); 
+0

Mi è davvero piaciuta la tua risposta originale. LINQ è stato mio amico per un po '. Non avevo mai usato saltare e prendere. Grazie. – LJM

+0

@L. Moser: Nessun problema - cambiato anche tu. :) E sì, penso di scoprire un nuovo metodo LINQ utile ogni settimana o giù di lì. – Noldorin

+3

Mentre il Linq è a portata di mano, è MOLTO meno performante – Mario

5

È possibile farlo con Array.Copy o LINQ.

var letters = string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i" }; 

int length = letters.Length - 2; 
var items = new string[length]; 
Array.Copy(letters, 1, items, 0, length); 
// or 
var items = letters.Skip(1).Take(length).ToArray(); 
1
string[] s = initialize the array... 

var subset = s.Skip(1).Take(s.Length - 2).ToArray(); 
+0

soluzione interessante – JohnIdol

2

Array.Copy() lo farà per voi, ma avete ancora di creare il nuovo array con le sue dimensioni corrette.

30

Linq è tutto bello e sgargianti, ma se siete in cerca di un 1-liner si può solo mettere insieme le proprie funzioni di utilità:

static class ArrayUtilities 
{ 
    // create a subset from a range of indices 
    public static T[] RangeSubset<T>(this T[] array, int startIndex, int length) 
    { 
     T[] subset = new T[length]; 
     Array.Copy(array, startIndex, subset, 0, length); 
     return subset; 
    } 

    // create a subset from a specific list of indices 
    public static T[] Subset<T>(this T[] array, params int[] indices) 
    { 
     T[] subset = new T[indices.Length]; 
     for (int i = 0; i < indices.Length; i++) 
     { 
      subset[i] = array[indices[i]]; 
     } 
     return subset; 
    } 
} 

Allora si potrebbe effettuare le seguenti operazioni:

 char[] original = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 

     // array containing 'b' - 'f' 
     char[] rangeSubset = original.RangeSubset(1, original.Length - 2); 

     // array containing 'c', 'd', and 'f' 
     char[] specificSubset = original.Subset(2, 3, 5); 
+2

Mi piace molto questa soluzione. –

0

Se si desidera evitare l'indicizzazione manuale della matrice. Non cercare di tirare richiesta che ovunque però:

var newArray = oldArray.Skip(1).Reverse().Skip(1).Reverse().ToArray() 
+0

Questo non sembra rilasciare l'ultimo elemento. –

+0

grazie @NathanTuggy, ho dimenticato. – Tobias

2

È possibile utilizzare ArraySegment<T> struttura come di seguito:

var arr = new[] { 1, 2, 3, 4, 5 }; 
var offset = 1; 
var count = 2; 
var subset = new ArraySegment<int>(arr, offset, count) 
      .ToArray(); // output: { 2, 3 } 

Controllare qui per un extension method che fa uso di ancora più facile.