2009-11-24 5 views
31

Si j'ai un tableau avec 12 éléments et que je veux un nouveau tableau qui laisse tomber les premier et 12ème éléments. Par exemple, si mon tableau ressemble à ceci:Sous-ensemble de la matrice en C#

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

Je veux soit transformer ou créer un nouveau tableau qui ressemble à

__ __ __ __ __ __ __ __ __ __ 

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

Je sais que je peux le faire par itérer sur eux. Je me demandais juste s'il y avait une manière plus propre construite dans C#.

** MISE À JOUR POUR FIXER UN TYPO. Changé 10 éléments en 12 éléments.

+0

Cependant, "j" n'est pas le 10ème élément du tableau? Ou voulez-vous dire premier et dernier éléments? –

Répondre

66

LINQ est votre ami. :)

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

Un peu moins efficace que de créer manuellement le tableau et itérer dessus bien sûr, mais bien simple, ...

La méthode légèrement lengithier qui utilise Array.Copy est le suivant.

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

J'ai vraiment aimé votre réponse originale. LINQ a été mon ami pendant un certain temps. Je n'avais jamais utilisé skip and take. Merci. – LJM

+0

@L. Moser: Pas de problème - changé de retour aussi. :) Et oui, je pense que je découvre une nouvelle méthode LINQ utile chaque semaine. – Noldorin

+3

Alors que le Linq est pratique, il est BEAUCOUP moins performant – Mario

5

Vous pouvez le faire avec Array.Copy ou 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

solution intéressante – JohnIdol

2

Array.Copy() va le faire pour vous, mais vous devez toujours créer votre nouveau tableau avec sa taille correcte.

30

Linq est tout gentil et tape à l'oeil, mais si vous cherchez un 1-liner vous pouvez simplement jeter ensemble vos propres fonctions d'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; 
    } 
} 

Ainsi, vous pouvez alors effectuer les opérations suivantes:

 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

J'aime vraiment cette solution. –

0

Si vous souhaitez éviter d'indexer manuellement la baie. Ne pas essayer de tirer la demande que si partout:

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

Cela ne semble pas laisser tomber le dernier élément. –

+0

merci @NathanTuggy, oublié à ce sujet. – Tobias

2

Vous pouvez utiliser la structure ArraySegment<T> comme ci-dessous:

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 } 

Vérifiez ici pour une extension method qui utilise encore plus facile.