2009-11-24 18 views
31

Si tengo una matriz con 12 elementos y quiero una nueva matriz con la que se eliminen los elementos primero y 12º. Por ejemplo, si mi matriz se ve así:Subconjunto de matriz en C#

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

Quiero ya sea transformarlo o crear una nueva matriz que se parece a

__ __ __ __ __ __ __ __ __ __ 

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

sé que puedo hacerlo iterando sobre ellos. Me preguntaba si había una forma más limpia integrada en C#.

** ACTUALIZADO PARA ARREGLAR UN TYPO. Cambió 10 elementos a 12 elementos.

+0

¿No es "j" el décimo elemento de la matriz? ¿O te refieres al primer y al último elemento? –

Respuesta

66

LINQ es tu amigo. :)

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

Algo menos eficiente que la creación manual de la matriz y la iteración en que, por supuesto, pero lejos de simple ...

El método ligeramente lengithier que utiliza Array.Copy es la siguiente.

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

Me gustó mucho su respuesta original. LINQ ha sido mi amigo por algún tiempo. Yo nunca había usado saltar y tomar. Gracias. – LJM

+0

@L. Moser: No hay problema, cambió de nuevo también. :) Y sí, creo que descubro un nuevo y útil método LINQ cada semana más o menos. – Noldorin

+3

Si bien el Linq es útil, es MUCHO menos eficiente – Mario

5

Puede hacerlo 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

solución interesante – JohnIdol

2

Array.Copy() lo hará por usted, pero usted todavía tiene que crear su nueva matriz con su tamaño correcto.

30

LINQ es todo lo agradable y elegante, pero si usted está buscando un 1-liner que sólo se ponían juntas sus propias funciones de utilidad:

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

Así entonces se podría hacer lo siguiente:

 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

Me gusta mucho esta solución. –

0

Si desea evitar la indexación manual de la matriz. No trate de tirar de la solicitud de que en cualquier lugar sin embargo:

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

Esto no parece soltar el último elemento. –

+0

gracias @NathanTuggy, se olvidó de eso. – Tobias

2

Puede utilizar ArraySegment<T> estructura, como a continuación:

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 } 

Marque aquí para una extension method que hace uso de ella aún más fácil.

Cuestiones relacionadas