Obtention d'un sous-tableau à partir d'un tableau existant

335

J'ai un tableau X de 10 éléments. Je voudrais créer un nouveau tableau contenant tous les éléments de X qui commencent à l'index 3 et se terminent à l'index 7. Bien sûr, je peux facilement écrire une boucle qui le fera pour moi mais je voudrais garder mon code aussi propre que possible . Existe-t-il une méthode en C # qui peut le faire pour moi?

Quelque chose comme (pseudo code):

Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)

Array.Copyne correspond pas à mes besoins . J'ai besoin que les éléments du nouveau tableau soient des clones. Array.copyest juste un memcpyéquivalent C-Style , ce n'est pas ce que je recherche.

user88637
la source
7
@Kirtan - ce "dup" veut spécifiquement IEnumerable <T> - qui est différent et a des solutions optimales différentes; OMI
Marc Gravell
Ainsi, les deux lignes qu'il faudrait pour déclarer le nouveau tableau et appeler .Copy () ne sont pas du "code propre"?
Ed S.
2
@Ed Swangren - pas si vous avez besoin de le faire au milieu d'une expression enchaînée, non ;-p
Marc Gravell
2
La réponse de ShaggyUk est probablement la bonne: stackoverflow.com/questions/943635/…
Dykam

Réponses:

469

Vous pouvez l'ajouter comme méthode d'extension:

public static T[] SubArray<T>(this T[] data, int index, int length)
{
    T[] result = new T[length];
    Array.Copy(data, index, result, 0, length);
    return result;
}
static void Main()
{
    int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int[] sub = data.SubArray(3, 4); // contains {3,4,5,6}
}

Mise à jour du re clonage (ce qui n'était pas évident dans la question d'origine). Si vous vraiment voulez un clone profond; quelque chose comme:

public static T[] SubArrayDeepClone<T>(this T[] data, int index, int length)
{
    T[] arrCopy = new T[length];
    Array.Copy(data, index, arrCopy, 0, length);
    using (MemoryStream ms = new MemoryStream())
    {
        var bf = new BinaryFormatter();
        bf.Serialize(ms, arrCopy);
        ms.Position = 0;
        return (T[])bf.Deserialize(ms);
    }
}

Cela nécessite cependant que les objets soient sérialisables ( [Serializable]ou ISerializable). Vous pouvez facilement se substituer à tout autre sérialiseur selon le cas - XmlSerializer, DataContractSerializer, protobuf-net, etc.

Notez que le clone profond est délicat sans sérialisation; en particulier, il ICloneableest difficile de faire confiance dans la plupart des cas.

Marc Gravell
la source
1
(évidemment, utiliser un index de fin plutôt qu'une longueur est un simple changement; j'ai posté "tel quel" car c'est l'usage le plus "typique")
Marc Gravell
1
Alors ... dur; cela ne fait pas ça .... vous auriez probablement besoin d'utiliser la sérialisation pour réaliser quelque chose de similaire
Marc Gravell
1
voir ma réponse pour quelques alternatives et un lien vers plusieurs implémentations. la partie sur le faire dans un sous-tableau est vraiment assez triviale, ce que vous voulez vraiment, c'est le bit de clonage et c'est une question complexe et quelque peu ouverte qui dépend entièrement de vos attentes quant à ce que devrait être un comportement `` correct '' .
ShuggyCoUk
2
C'est sympa. Et il est particulièrement bon de souligner que ICloneable n'est pas fiable, car oh, l'est-il jamais.
Marcus Griep
1
Merci d'avoir souligné les problèmes de clonage profond en C #. C'est vraiment dommage, car la copie en profondeur est une opération fondamentale .
Dimitri C.
317

Vous pouvez utiliser Array.Copy(...)pour copier dans le nouveau tableau après l'avoir créé, mais je ne pense pas qu'il existe une méthode qui crée le nouveau tableau et copie une gamme d'éléments.

Si vous utilisez .NET 3.5, vous pouvez utiliser LINQ:

var newArray = array.Skip(3).Take(5).ToArray();

mais ce sera un peu moins efficace.

Voir cette réponse à une question similaire pour des options pour des situations plus spécifiques.

Jon Skeet
la source
+1 J'aime aussi cette variante. Jon, pouvez-vous expliquer pourquoi cela est jugé moins efficace?
Ian Roke
@ Jon: Pour répondre à la question, ne serait-ce pas "Take (5)"? @Ian: l'approche Array.Copy n'implique pas d'énumérateur, et sera très probablement une simple memcopie ...
Marc Gravell
@Marc: Oui en effet. Trop de questions écrémées :)
Jon Skeet
11
@Ian: L'approche LINQ introduit deux niveaux d'indirection (les itérateurs), doit ignorer explicitement les éléments et ne sait pas quelle taille le tableau final va avoir à l'avance. Pensez à prendre la seconde moitié d'un tableau de deux millions d'éléments: une approche simple «créer un tableau cible, copier» copiera simplement le bloc requis sans toucher les autres éléments, et en une seule fois. L'approche LINQ parcourt le tableau jusqu'à ce qu'il atteigne le point de départ, puis commence à prendre des valeurs, à créer un tampon (en augmentant la taille du tampon et en copiant périodiquement). Beaucoup moins efficace.
Jon Skeet
si 5 est EndIndexm, alors la bonne question est array.Skip (3) .Take (5-3 + 1) .ToArray (); c'est à dire. array.Skip (StartIndex) .Take (EndIndex-StartIndex + 1) .ToArray ();
Klaus78
74

Avez-vous pensé à utiliser ArraySegment?

http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx

Alex Black
la source
1
Il fait probablement ce que vous voulez, mais il ne prend pas en charge la syntaxe de tableau par défaut, ni IEnumerable, donc ce n'est pas particulièrement propre.
Alex Black,
5
Cela nécessite plus de votes positifs. Dans ma propre exp, la copie d'ArraySegment est aussi légèrement plus rapide (après tout, j'utilise des tableaux pour des trucs critiques pour la vitesse) ..
nawfal
5
@AlexBlack Il ressemble à .NET 4.5 , il implémente IEnumerable<T>et une variété d'autres interfaces utiles.
pswg
1
Comment utiliseriez-vous ArraySegmentpour répondre à la question d'origine?
Craig McQueen
2
@CraigMcQueen - Essayez l'approche à ligne unique suivante:IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
skia.heliou
36

Je vois que vous voulez faire du clonage, pas seulement copier des références. Dans ce cas, vous pouvez utiliser .Selectpour projeter les membres du tableau sur leurs clones. Par exemple, si vos éléments sont implémentés, IClonablevous pouvez faire quelque chose comme ceci:

var newArray = array.Skip(3).Take(5).Select(eachElement => eachElement.Clone()).ToArray();

Remarque: Cette solution nécessite .NET Framework 3.5.

zvolkov
la source
C'est plus élégant.
smwikipedia
Ceci est exactement ce que je cherchais. Cela fonctionne pour tout IEnumerable. Je peux obtenir un IEnumerable, IList, IArray, etc ... avec un minimum de bruit, en ligne si je dois. Si je n'ai pas besoin de la copie complète, je supprime simplement le fichier Select. La chute Skipou Takeme permet de contrôler la plage. Alternativement, je peux le mélanger avec SkipWhileet / ou TakeWhile.
Mike
33

Le code suivant le fait sur une seule ligne:

// Source array
string[] Source = new string[] { "A", "B", "C", "D" };
// Extracting a slice into another array
string[] Slice = new List<string>(Source).GetRange(2, 2).ToArray();
Volker
la source
Ligne unique et pas besoin d'ajouter Linq. C'est ma façon préférée.
Dimitris
Pourtant, cela ne clone pas la source ... mais c'est quand même une bonne approche
IG Pascual
1
Il doit cloner la source car ToArray: (1) crée un nouveau tableau et (2) exécute Array.Copy. Au final, Source et Slice sont deux objets distincts. L'approche est correcte, cependant, je préfère Array.Copy: referencesource.microsoft.com/#mscorlib/system/collections/…
Krauss
13

En C # 8 , ils ont introduit un nouveau Rangeet le Indextype

int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Index i1 = 3;  // number 3 from beginning
Index i2 = ^4; // number 4 from end
var slice = a[i1..i2]; // { 3, 4, 5 }
Prasanth Louis
la source
12
string[] arr = { "Parrot" , "Snake" ,"Rabbit" , "Dog" , "cat" };

arr = arr.ToList().GetRange(0, arr.Length -1).ToArray();
user3698437
la source
8

S'appuyant sur la réponse de Marc mais en ajoutant le comportement de clonage souhaité

public static T[] CloneSubArray<T>(this T[] data, int index, int length)
    where T : ICloneable
{
    T[] result = new T[length];
    for (int i = 0; i < length; i++)
    { 
        var original = data[index + i];
        if (original != null)
            result[i] = (T)original.Clone();            
    return result;
}

Et si implémenter ICloneable ressemble trop à un travail acharné, réfléchissez en utilisant la bibliothèque copiable de Håvard Stranden pour faire le gros du travail nécessaire.

using OX.Copyable;

public static T[] DeepCopySubArray<T>(
    this T[] data, int index, int length)
{
    T[] result = new T[length];
    for (int i = 0; i < length; i++)
    { 
        var original = data[index + i];
        if (original != null)
            result[i] = (T)original.Copy();            
    return result;
}

Notez que l'implémentation OX.Copyable fonctionne avec:

Pour que la copie automatisée fonctionne, cependant, l'une des déclarations suivantes doit contenir par exemple:

  • Son type doit avoir un constructeur sans paramètre, ou
  • Il doit être copiable, ou
  • Il doit avoir un IInstanceProvider enregistré pour son type.

Cela devrait donc couvrir presque toutes les situations que vous avez. Si vous clonez des objets où le sous-graphique contient des éléments tels que les connexions db ou les poignées de fichier / flux, vous avez évidemment des problèmes, mais c'est vrai pour toute copie approfondie généralisée.

Si vous souhaitez utiliser une autre approche de copie approfondie à la place, cet article en répertorie plusieurs autres , je vous suggère donc de ne pas essayer d'écrire la vôtre.

ShuggyCoUk
la source
La première est probablement la solution souhaitée, car il demande le clonage. Notez qu'avec la méthode Copy, vous n'avez probablement même pas besoin de vérifier la valeur null, car c'est une méthode d'extension, si la méthode elle-même fait déjà cette chose. Ça vaut le coup d'essayer.
Dykam
Oui, j'ai noté la vérification nulle mais je ne voulais pas confondre l'OP au cas où il n'aurait pas lu la source.
ShuggyCoUk
2
Juste une petite note: la dernière version de Copyable sur GitHub ne nécessite pas que les objets aient un constructeur sans paramètre. :) Voir github.com/havard/copyable
Håvard S
8

Vous pouvez le faire assez facilement;

    object[] foo = new object[10];
    object[] bar = new object[7];   
    Array.Copy(foo, 3, bar, 0, 7);  
RandomNickName42
la source
Non, la barre sera toujours nulle. Array.Copy ne crée pas comme par magie un nouveau tableau, d'autant plus que la barre n'est pas passée avec ref ou out.
Zr40
2
oh ya hey, vous avez raison, je l'ai fait à la hâte, mais bon, peut-être que lorsque vous écrivez votre critique, vous devriez mettre la correction, la critique constructive est tellement plus utile pour tout le monde. donc avant ce tableau.copy vous faites un "bar = nouvel objet [7];"
RandomNickName42
4

Je pense que le code que vous recherchez est:

Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)

Sean
la source
Je pense que je me suis fait de bons amis ici ... même réponse que vous;) et j'ai beaucoup voté !! hah !! Quoi qu'il en soit, de bons moments de bons moments.
RandomNickName42
3

Au lieu de copier les données, vous pouvez créer un wrapper qui vous donne accès à une partie du tableau d'origine comme s'il s'agissait d'une copie de la partie du tableau. L'avantage est que vous n'obtenez pas une autre copie des données en mémoire, et l'inconvénient est une légère surcharge lors de l'accès aux données.

public class SubArray<T> : IEnumerable<T> {

   private T[] _original;
   private int _start;

   public SubArray(T[] original, int start, int len) {
      _original = original;
      _start = start;
      Length = len;
   }

   public T this[int index] {
      get {
         if (index < 0 || index >= Length) throw new IndexOutOfRangeException();
         return _original[_start + index];
      }
   }

   public int Length { get; private set; }

   public IEnumerator<T> GetEnumerator() {
      for (int i = 0; i < Length; i++) {
        yield return _original[_start + i];
      }
   }

   IEnumerator IEnumerable.GetEnumerator() {
      return GetEnumerator();
   }

}

Usage:

int[] original = { 1, 2, 3, 4, 5 };
SubArray<int> copy = new SubArray<int>(original, 2, 2);

Console.WriteLine(copy.Length); // shows: 2
Console.WriteLine(copy[0]); // shows: 3
foreach (int i in copy) Console.WriteLine(i); // shows 3 and 4
Guffa
la source
@Robert: Non, ce n'est pas le cas. Essayez d'utiliser un ArraySegment à la place, et vous voyez que vous ne pouvez ni accéder aux éléments par index, ni parcourir les éléments.
Guffa
2

Array.ConstrainedCopy fonctionnera.

public static void ConstrainedCopy (
    Array sourceArray,
    int sourceIndex,
    Array destinationArray,
    int destinationIndex,
    int length
)
crauscher
la source
2
Cela ne fait que copier les données; il ne créera pas le nouveau tableau etc; et si le tableau est nouveau, nous pourrions utiliser Array.Copy qui est plus efficace (pas besoin de vérifications / annulations supplémentaires).
Marc Gravell
C'est vrai, mais la création d'un nouveau tableau n'est qu'une ligne de code et aucune nouvelle méthode n'est requise. Je suis d'accord que Array.Copy fonctionnera également.
crauscher
1

Il n'y a pas de méthode unique qui fera ce que vous voulez. Vous devrez rendre une méthode de clonage disponible pour la classe de votre tableau. Ensuite, si LINQ est une option:

Foo[] newArray = oldArray.Skip(3).Take(5).Select(item => item.Clone()).ToArray();

class Foo
{
    public Foo Clone()
    {
        return (Foo)MemberwiseClone();
    }
}
Thorarin
la source
1

Que diriez-vous d' utiliser Array.ConstrainedCopy :

int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8};
int[] ArrayTwo = new int[5];
Array.ConstrainedCopy(ArrayOne, 3, ArrayTwo, 0, 7-3);

Ci-dessous est mon message d'origine. Ça ne marchera pas

Vous pouvez utiliser Array.CopyTo :

int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8};
int[] ArrayTwo = new int[5];
ArrayOne.CopyTo(ArrayTwo,3); //starts copy at index=3 until it reaches end of
                             //either array
Mike
la source
1

Que dis-tu de ça:

public T[] CloneCopy(T[] array, int startIndex, int endIndex) where T : ICloneable
{
    T[] retArray = new T[endIndex - startIndex];
    for (int i = startIndex; i < endIndex; i++)
    {
        array[i - startIndex] = array[i].Clone();
    }
    return retArray;

}

Vous devez ensuite implémenter l'interface ICloneable sur toutes les classes sur lesquelles vous devez l'utiliser, mais cela devrait le faire.

RCIX
la source
1

Je ne sais pas à quel point c'est profond, mais:

MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()

C'est un peu de surcharge, mais cela pourrait éliminer une méthode inutile.

SCNerd
la source
1

C # 8 a fourni une fonctionnalité appelée Range pour obtenir la sous-zone du début à la fin de l'index. vous pouvez l'utiliser comme ça.

Index i1 = 3; // number 3 from beginning  
Index i2 = ^4; // number 4 from end  
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
var slice = a[i1..i2]; // { 3, 4, 5 }
vivek nuna
la source
Voilà des s ** t pythoniques fous. J'aime cela.
Ch3shire
Oui, c'est vraiment une fonctionnalité intéressante
vivek nuna
0

En ce qui concerne le clonage, je ne pense pas que la sérialisation appelle vos constructeurs. Cela peut casser les invariants de classe si vous faites des choses intéressantes dans le ctor.

Il semble que le pari le plus sûr soit les méthodes de clonage virtuel appelant les constructeurs de copie.

protected MyDerivedClass(MyDerivedClass myClass) 
{
  ...
}

public override MyBaseClass Clone()
{
  return new MyDerivedClass(this);
}
Hans Malherbe
la source
Que la sérialisation appelle vos constructeurs dépend du sérialiseur spécifique. Certains le font, d'autres non. Mais ceux qui n'offrent généralement pas de support de rappel pour vous permettre de faire les corrections nécessaires.
Marc Gravell
Cela met en évidence un autre point de friction de la sérialisation: vous devez fournir des constructeurs par défaut.
Hans Malherbe
0

Le clonage d'éléments dans un tableau n'est pas quelque chose qui peut être fait de manière universelle. Voulez-vous un clonage en profondeur ou une simple copie de tous les membres?

C'est parti pour l'approche du "meilleur effort": clonage d'objets à l'aide de l'interface ICloneable ou sérialisation binaire:

public static class ArrayExtensions
{
  public static T[] SubArray<T>(this T[] array, int index, int length)
  {
    T[] result = new T[length];

    for (int i=index;i<length+index && i<array.Length;i++)
    {
       if (array[i] is ICloneable)
          result[i-index] = (T) ((ICloneable)array[i]).Clone();
       else
          result[i-index] = (T) CloneObject(array[i]);
    }

    return result;
  }

  private static object CloneObject(object obj)
  {
    BinaryFormatter formatter = new BinaryFormatter();

    using (MemoryStream stream = new MemoryStream())
    {
      formatter.Serialize(stream, obj);

      stream.Seek(0,SeekOrigin.Begin);

      return formatter.Deserialize(stream);
    }
  }
}

Ce n'est pas une solution parfaite, car il n'y en a tout simplement pas qui fonctionnera pour tout type d'objet.

Philippe Leybaert
la source
Cela ne devrait-il pas être quelque chose comme result [i-index] = (T) ...?
Donald Byrd
oui :) Et pas seulement ça. La limite de boucle est incorrecte. Je le réparerai. Merci!
Philippe Leybaert
0

Vous pouvez prendre des cours faits par Microsoft:

internal class Set<TElement>
{
    private int[] _buckets;
    private Slot[] _slots;
    private int _count;
    private int _freeList;
    private readonly IEqualityComparer<TElement> _comparer;

    public Set()
        : this(null)
    {
    }

    public Set(IEqualityComparer<TElement> comparer)
    {
        if (comparer == null)
            comparer = EqualityComparer<TElement>.Default;
        _comparer = comparer;
        _buckets = new int[7];
        _slots = new Slot[7];
        _freeList = -1;
    }

    public bool Add(TElement value)
    {
        return !Find(value, true);
    }

    public bool Contains(TElement value)
    {
        return Find(value, false);
    }

    public bool Remove(TElement value)
    {
        var hashCode = InternalGetHashCode(value);
        var index1 = hashCode % _buckets.Length;
        var index2 = -1;
        for (var index3 = _buckets[index1] - 1; index3 >= 0; index3 = _slots[index3].Next)
        {
            if (_slots[index3].HashCode == hashCode && _comparer.Equals(_slots[index3].Value, value))
            {
                if (index2 < 0)
                    _buckets[index1] = _slots[index3].Next + 1;
                else
                    _slots[index2].Next = _slots[index3].Next;
                _slots[index3].HashCode = -1;
                _slots[index3].Value = default(TElement);
                _slots[index3].Next = _freeList;
                _freeList = index3;
                return true;
            }
            index2 = index3;
        }
        return false;
    }

    private bool Find(TElement value, bool add)
    {
        var hashCode = InternalGetHashCode(value);
        for (var index = _buckets[hashCode % _buckets.Length] - 1; index >= 0; index = _slots[index].Next)
        {
            if (_slots[index].HashCode == hashCode && _comparer.Equals(_slots[index].Value, value))
                return true;
        }
        if (add)
        {
            int index1;
            if (_freeList >= 0)
            {
                index1 = _freeList;
                _freeList = _slots[index1].Next;
            }
            else
            {
                if (_count == _slots.Length)
                    Resize();
                index1 = _count;
                ++_count;
            }
            int index2 = hashCode % _buckets.Length;
            _slots[index1].HashCode = hashCode;
            _slots[index1].Value = value;
            _slots[index1].Next = _buckets[index2] - 1;
            _buckets[index2] = index1 + 1;
        }
        return false;
    }

    private void Resize()
    {
        var length = checked(_count * 2 + 1);
        var numArray = new int[length];
        var slotArray = new Slot[length];
        Array.Copy(_slots, 0, slotArray, 0, _count);
        for (var index1 = 0; index1 < _count; ++index1)
        {
            int index2 = slotArray[index1].HashCode % length;
            slotArray[index1].Next = numArray[index2] - 1;
            numArray[index2] = index1 + 1;
        }
        _buckets = numArray;
        _slots = slotArray;
    }

    internal int InternalGetHashCode(TElement value)
    {
        if (value != null)
            return _comparer.GetHashCode(value) & int.MaxValue;
        return 0;
    }

    internal struct Slot
    {
        internal int HashCode;
        internal TElement Value;
        internal int Next;
    }
}

puis

public static T[] GetSub<T>(this T[] first, T[] second)
    {
        var items = IntersectIteratorWithIndex(first, second);
        if (!items.Any()) return new T[] { };


        var index = items.First().Item2;
        var length = first.Count() - index;
        var subArray = new T[length];
        Array.Copy(first, index, subArray, 0, length);
        return subArray;
    }

    private static IEnumerable<Tuple<T, Int32>> IntersectIteratorWithIndex<T>(IEnumerable<T> first, IEnumerable<T> second)
    {
        var firstList = first.ToList();
        var set = new Set<T>();
        foreach (var i in second)
            set.Add(i);
        foreach (var i in firstList)
        {
            if (set.Remove(i))
                yield return new Tuple<T, Int32>(i, firstList.IndexOf(i));
        }
    }
Smagin Alexey
la source
0

C'est la façon optimale, j'ai trouvé, de le faire:

private void GetSubArrayThroughArraySegment() {
  int[] array = { 10, 20, 30 };
  ArraySegment<int> segment = new ArraySegment<int>(array,  1, 2);
  Console.WriteLine("-- Array --");
  int[] original = segment.Array;
  foreach (int value in original)
  {
    Console.WriteLine(value);
  }
  Console.WriteLine("-- Offset --");
  Console.WriteLine(segment.Offset);
  Console.WriteLine("-- Count --");
  Console.WriteLine(segment.Count);

  Console.WriteLine("-- Range --");
  for (int i = segment.Offset; i <= segment.Count; i++)
  {
    Console.WriteLine(segment.Array[i]);
  }
}

J'espère que ça aide!

OscarMas
la source
0

utiliser la méthode d'extension:

public static T[] Slice<T>(this T[] source, int start, int end)
    {
        // Handles negative ends.
        if (end < 0)
        {
            end = source.Length + end;
        }
        int len = end - start;

        // Return new array.
        T[] res = new T[len];
        for (int i = 0; i < len; i++)
        {
            res[i] = source[i + start];
        }
        return res;
    }

et vous pouvez l'utiliser

var NewArray = OldArray.Slice(3,7);
Erwin Draconis
la source
0

Code de System.Private.CoreLib.dll:

public static T[] GetSubArray<T>(T[] array, Range range)
{
    if (array == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
    }
    (int Offset, int Length) offsetAndLength = range.GetOffsetAndLength(array.Length);
    int item = offsetAndLength.Offset;
    int item2 = offsetAndLength.Length;
    if (default(T) != null || typeof(T[]) == array.GetType())
    {
        if (item2 == 0)
        {
            return Array.Empty<T>();
        }
        T[] array2 = new T[item2];
        Buffer.Memmove(ref Unsafe.As<byte, T>(ref array2.GetRawSzArrayData()), ref Unsafe.Add(ref Unsafe.As<byte, T>(ref array.GetRawSzArrayData()), item), (uint)item2);
        return array2;
    }
    T[] array3 = (T[])Array.CreateInstance(array.GetType().GetElementType(), item2);
    Array.Copy(array, item, array3, 0, item2);
    return array3;
}


Ezequiel Maygua
la source
0

Il ne répond pas à vos exigences de clonage, mais il semble plus simple que de nombreuses réponses:

Array NewArray = new ArraySegment(oldArray,BeginIndex , int Count).ToArray();
Mr. Boy
la source
-1
public   static   T[]   SubArray<T>(T[] data, int index, int length)
        {
            List<T> retVal = new List<T>();
            if (data == null || data.Length == 0)
                return retVal.ToArray();
            bool startRead = false;
            int count = 0;
            for (int i = 0; i < data.Length; i++)
            {
                if (i == index && !startRead)
                    startRead = true;
                if (startRead)
                {

                    retVal.Add(data[i]);
                    count++;

                    if (count == length)
                        break;
                }
            }
            return retVal.ToArray();
        }
Binay Rana
la source