How do I clone a range of array elements to a new array?

前端 未结 25 1005
北海茫月
北海茫月 2020-11-22 16:07

I have an array X of 10 elements. I would like to create a new array containing all the elements from X that begin at index 3 and ends in index 7. Sure I can easily write a

相关标签:
25条回答
  • 2020-11-22 16:48

    As an alternative to copying the data you can make a wrapper that gives you access to a part of the original array as if it was a copy of the part of the array. The advantage is that you don't get another copy of the data in memory, and the drawback is a slight overhead when accessing the data.

    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
    
    0 讨论(0)
  • 2020-11-22 16:48

    Array.ConstrainedCopy will work.

    public static void ConstrainedCopy (
        Array sourceArray,
        int sourceIndex,
        Array destinationArray,
        int destinationIndex,
        int length
    )
    
    0 讨论(0)
  • 2020-11-22 16:48

    Cloning elements in an array is not something that can be done in a universal way. Do you want deep cloning or a simple copy of all members?

    Let's go for the "best effort" approach: cloning objects using the ICloneable interface or binary serialization:

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

    This is not a perfect solution, because there simply is none that will work for any type of object.

    0 讨论(0)
  • 2020-11-22 16:50
    string[] arr = { "Parrot" , "Snake" ,"Rabbit" , "Dog" , "cat" };
    
    arr = arr.ToList().GetRange(0, arr.Length -1).ToArray();
    
    0 讨论(0)
  • 2020-11-22 16:51

    In C# 8, they've introduced a new Range and Index type, which can be used like this:

    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 }
    

    References:

    • https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#ranges-and-indices
    • https://devblogs.microsoft.com/dotnet/building-c-8-0/
    0 讨论(0)
  • 2020-11-22 16:52

    How about useing 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);
    

    Below is my original post. It will not work

    You could use 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
    
    0 讨论(0)
提交回复
热议问题