Mendapatkan sub-array dari array yang ada

335

Saya memiliki array X dari 10 elemen. Saya ingin membuat array baru yang berisi semua elemen dari X yang dimulai pada indeks 3 dan berakhir pada indeks 7. Tentu saya dapat dengan mudah menulis sebuah loop yang akan melakukannya untuk saya, tetapi saya ingin menjaga kode saya sebersih mungkin . Apakah ada metode dalam C # yang dapat melakukannya untuk saya?

Sesuatu seperti (kode semu):

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

Array.Copytidak sesuai dengan kebutuhan saya . Saya perlu item dalam array baru menjadi klon. Array.copyhanya memcpysetara dengan C-Style , bukan itu yang saya cari.

pengguna88637
sumber
7
@Kirtan - "dup" itu secara khusus menginginkan IEnumerable <T> - yang berbeda dan memiliki solusi optimal yang berbeda; IMO
Marc Gravell
Jadi, dua baris yang diperlukan untuk mendeklarasikan array baru dan memanggil .Copy () bukan "kode bersih"?
Ed S.
2
@ Ed Swangren - tidak jika Anda perlu melakukannya di tengah-tengah ekspresi dirantai, tidak ;-p
Marc Gravell
2
Jawaban ShaggyUk mungkin adalah jawaban yang benar: stackoverflow.com/questions/943635/…
Dykam

Jawaban:

469

Anda dapat menambahkannya sebagai metode ekstensi:

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

Perbarui kembali kloning (yang tidak jelas dalam pertanyaan asli). Jika Anda benar - benar menginginkan klon yang dalam; sesuatu seperti:

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

Ini memang membutuhkan objek yang dapat serial ( [Serializable]atau ISerializable). Anda bisa dengan mudah mengganti untuk setiap serializer lain yang sesuai - XmlSerializer, DataContractSerializer, protobuf-net, dll

Perhatikan bahwa klon dalam sulit tanpa serialisasi; khususnya, ICloneablesulit dipercaya dalam banyak kasus.

Marc Gravell
sumber
1
(jelas menggunakan indeks akhir daripada panjang adalah perubahan sederhana; saya kirimkan "sebagaimana adanya" karena itu adalah lebih "khas" penggunaan)
Marc Gravell
1
Lalu ... tangguh; tidak melakukan itu .... Anda mungkin akan perlu menggunakan serialisasi untuk mencapai sesuatu yang mirip
Marc Gravell
1
lihat jawaban saya untuk beberapa alternatif dan tautan ke beberapa implementasi. bagian tentang melakukannya ke sub array benar-benar agak sepele, apa yang Anda inginkan adalah bit kloning dan itu adalah pertanyaan yang kompleks dan agak terbuka yang sepenuhnya bergantung pada harapan Anda tentang apa yang seharusnya menjadi perilaku yang 'benar' .
ShuggyCoUk
2
Ini bagus. Dan sangat bagus untuk menunjukkan bahwa ICloneable tidak dapat diandalkan, karena oh, pernahkah.
Marcus Griep
1
Terima kasih telah menggarisbawahi masalah dengan kloning yang dalam di C #. Sungguh memalukan, karena penyalinan yang dalam adalah operasi yang mendasar .
Dimitri C.
317

Anda dapat menggunakannya Array.Copy(...)untuk menyalin ke array baru setelah Anda membuatnya, tapi saya rasa tidak ada metode yang menciptakan array baru dan menyalin berbagai elemen.

Jika Anda menggunakan .NET 3.5 Anda bisa menggunakan LINQ:

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

tapi itu akan menjadi kurang efisien.

Lihat jawaban ini untuk pertanyaan serupa untuk opsi untuk situasi yang lebih spesifik.

Jon Skeet
sumber
+1 Saya suka variasi ini juga. Jon, dapatkah Anda memperluas mengapa ini dianggap kurang efisien?
Ian Roke
@ Jon: Untuk mencocokkan pertanyaan, bukankah itu "Ambil (5)"? @Ian: pendekatan Array.Copy tidak melibatkan enumerator, dan paling mungkin akan menjadi memcopy lurus ...
Marc Gravell
@ Markc: Ya, tentu saja. Terlalu banyak pertanyaan skimming :)
Jon Skeet
11
@Ian: Pendekatan LINQ memperkenalkan dua tingkat tipuan (iterator), harus secara eksplisit melewati item, dan tidak tahu seberapa besar array final akan menjadi sebelumnya. Pertimbangkan untuk mengambil paruh kedua dari array dua juta elemen: pendekatan sederhana "buat target array, salin" hanya akan menyalin blok yang diperlukan tanpa menyentuh elemen lain, dan sekaligus. Pendekatan LINQ akan berjalan melalui array sampai mencapai titik awal, kemudian mulai mengambil nilai, membangun buffer (menambah ukuran buffer dan menyalin secara berkala). Jauh lebih efisien.
Jon Skeet
jika 5 adalah EndIndexm, maka pertanyaan yang benar adalah array. Skip (3). Ambil (5-3 + 1) .ToArray (); yaitu. array.Skip (StartIndex) .Take (EndIndex-StartIndex + 1) .ToArray ();
Klaus78
74

Sudahkah Anda mempertimbangkan untuk menggunakan ArraySegment?

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

Alex Black
sumber
1
Mungkin melakukan apa yang Anda inginkan, tetapi tidak mendukung sintaks array default, juga tidak mendukung IEnumerable, jadi tidak terlalu bersih.
Alex Black
5
Ini membutuhkan lebih banyak suara positif. Dalam exp saya sendiri, menyalin ArraySegment juga sedikit lebih cepat (setelah semua saya menggunakan array untuk hal-hal penting kecepatan) ..
nawfal
5
@ AlexBlack Sepertinya pada . NET 4.5 , itu mengimplementasikan IEnumerable<T>dan berbagai antarmuka yang berguna lainnya.
pswg
1
Bagaimana Anda akan digunakan ArraySegmentuntuk menjawab pertanyaan awal?
Craig McQueen
2
@CraigMcQueen - Cobalah pendekatan single-line berikut:IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
skia.heliou
36

Saya melihat Anda ingin melakukan Kloning, bukan hanya menyalin referensi. Dalam hal ini Anda dapat menggunakan .Selectuntuk memproyeksikan anggota array ke klonnya. Misalnya, jika elemen IClonableAnda diimplementasikan, Anda dapat melakukan sesuatu seperti ini:

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

Catatan: Solusi ini membutuhkan .NET Framework 3.5.

zvolkov
sumber
Ini lebih elegan.
smwikipedia
Ini persis apa yang saya cari. Ini bekerja untuk siapa saja IEnumerable. Saya bisa mendapatkan IEnumerable, IList, IArray, dll ... dengan sedikit rewel, inline jika saya perlu. Jika saya tidak membutuhkan salinan yang dalam, saya hanya menghapus Select. Menjatuhkan Skipatau Takememungkinkan saya untuk mengontrol rentang. Atau, saya bisa mencampurnya dengan SkipWhiledan / atau TakeWhile.
Mike
33

Kode berikut melakukannya dalam satu baris:

// 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
sumber
Lajang garis dan tidak perlu menambahkan Linq. Ini cara yang saya sukai.
Dimitris
Tetap saja itu tidak mengkloning sumbernya ... tapi itu pendekatan yang bagus
IG Pascual
1
Harus mengkloning sumber karena ToArray: (1) membuat array baru dan (2) mengeksekusi Array.Copy. Pada akhirnya Sumber dan Iris adalah dua objek terpisah. Pendekatannya benar, namun, saya lebih suka Array.Copy: Referenceource.microsoft.com/#mscorlib/system/collections/…
Krauss
13

Di C # 8 mereka sudah memperkenalkan yang baru Rangedan Indexketik

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
sumber
12
string[] arr = { "Parrot" , "Snake" ,"Rabbit" , "Dog" , "cat" };

arr = arr.ToList().GetRange(0, arr.Length -1).ToArray();
pengguna3698437
sumber
8

Membangun jawaban Marc tetapi menambahkan perilaku kloning yang diinginkan

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

Dan jika menerapkan ICloneable terlalu banyak seperti kerja keras yang reflektif menggunakan perpustakaan Håvard Stranden Copyable untuk melakukan pengangkatan berat yang diperlukan.

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

Perhatikan bahwa implementasi OX.Copyable berfungsi dengan salah satu dari:

Agar salinan otomatis berfungsi, salah satu pernyataan berikut harus berlaku misalnya:

  • Jenisnya harus memiliki konstruktor tanpa parameter, atau
  • Itu harus dapat disalin, atau
  • Itu harus memiliki IInstanceProvider terdaftar untuk jenisnya.

Jadi ini harus mencakup hampir semua situasi yang Anda miliki. Jika Anda mengkloning objek di mana sub grafik berisi hal-hal seperti koneksi db atau file / stream menangani Anda jelas memiliki masalah tetapi itu berlaku untuk setiap salinan yang digeneralisasi secara umum.

Jika Anda ingin menggunakan beberapa pendekatan penyalinan dalam, artikel ini mencantumkan beberapa yang lain, jadi saya sarankan untuk tidak mencoba menulis sendiri.

ShuggyCoUk
sumber
Yang pertama mungkin solusi yang diinginkan, karena ia meminta kloning. Perhatikan bahwa dengan metode Salin, Anda mungkin bahkan tidak perlu memeriksa nol, karena ini adalah metode ekstensi, jika metode itu sendiri sudah melakukan hal itu. Layak dicoba.
Dykam
Ya saya mencatat cek nol tetapi tidak ingin membingungkan OP jika dia tidak membaca sumbernya.
ShuggyCoUk
2
Hanya sidenote: Versi terbaru dari Copyable di GitHub tidak memerlukan objek untuk memiliki konstruktor tanpa parameter. :) Lihat github.com/havard/copyable
Håvard S
8

Anda dapat melakukan ini dengan cukup mudah;

    object[] foo = new object[10];
    object[] bar = new object[7];   
    Array.Copy(foo, 3, bar, 0, 7);  
RandomNickName42
sumber
Tidak, bilah akan tetap nol. Array.Copy tidak secara ajaib membuat array baru, terutama karena bar tidak lulus dengan ref atau keluar.
Zr40
2
oh ya hei, benar, saya melakukan ini dengan terburu-buru, tapi hei, mungkin ketika kritik tulisan Anda, Anda harus meletakkan koreksi, kritik konstruktif jauh lebih berguna bagi semua orang. jadi sebelum array.copy Anda melakukan "bar = objek baru [7];"
RandomNickName42
4

Saya pikir kode yang Anda cari adalah:

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

Sean
sumber
Saya pikir saya telah membuat beberapa teman baik di sini .... jawaban yang sama seperti Anda;) dan saya banyak dikecewakan !! hah !! Bagaimanapun, masa-masa indah masa-masa indah.
RandomNickName42
3

Sebagai alternatif untuk menyalin data Anda bisa membuat pembungkus yang memberi Anda akses ke bagian dari array asli seolah-olah itu adalah salinan dari bagian array. Keuntungannya adalah Anda tidak mendapatkan salinan data lainnya dalam memori, dan kekurangannya adalah sedikit overhead saat mengakses 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();
   }

}

Pemakaian:

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
sumber
@ Robert: Tidak, tidak. Cobalah untuk menggunakan ArraySegment sebagai gantinya, dan Anda melihat bahwa Anda tidak dapat mengakses item dengan indeks, tidak iterate melalui item.
Guffa
2

Array.ConstrainedCopy akan berfungsi.

public static void ConstrainedCopy (
    Array sourceArray,
    int sourceIndex,
    Array destinationArray,
    int destinationIndex,
    int length
)
pengrajin
sumber
2
Itu hanya menyalin data; itu tidak akan membuat array baru dll; dan jika array baru, kita bisa menggunakan Array.Copy yang lebih efisien (tidak perlu untuk pemeriksaan tambahan / rollback).
Marc Gravell
Itu benar, tetapi membuat Array baru hanya satu baris kode dan tidak diperlukan metode baru. Saya setuju bahwa Array.Copy akan bekerja juga.
crauscher
1

Tidak ada metode tunggal yang akan melakukan apa yang Anda inginkan. Anda perlu membuat metode klon tersedia untuk kelas dalam array Anda. Kemudian, jika LINQ adalah opsi:

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

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

Bagaimana dengan menggunakan 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);

Di bawah ini adalah posting asli saya. Itu tidak akan bekerja

Anda dapat menggunakan 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
sumber
1

Bagaimana dengan ini:

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;

}

Anda kemudian perlu mengimplementasikan antarmuka ICloneable di semua kelas yang Anda perlu gunakan ini tetapi itu harus dilakukan.

RCIX
sumber
1

Saya tidak yakin seberapa dalam itu sebenarnya, tetapi:

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

Ini sedikit overhead, tetapi mungkin memotong metode yang tidak perlu.

SCNerd
sumber
1

C # 8 telah menyediakan fitur yang disebut Range untuk mendapatkan subarry dari indeks awal hingga akhir. Anda bisa menggunakannya seperti ini.

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
sumber
Itu beberapa gila pythonic s ** t. Aku menyukainya.
Ch3shire
Ya, ini fitur yang sangat bagus
vivek nuna
0

Sejauh kloning berjalan, saya tidak berpikir serialisasi memanggil konstruktor Anda. Ini dapat merusak invarian kelas jika Anda melakukan hal-hal menarik di ctor's.

Tampaknya taruhan yang lebih aman adalah metode klon virtual yang memanggil copy constructor.

protected MyDerivedClass(MyDerivedClass myClass) 
{
  ...
}

public override MyBaseClass Clone()
{
  return new MyDerivedClass(this);
}
Hans Malherbe
sumber
Apakah serialisasi memanggil konstruktor Anda, terserah serializer tertentu. Ada yang melakukannya, ada yang tidak. Tetapi mereka yang biasanya tidak menawarkan dukungan panggilan balik untuk memungkinkan Anda melakukan perbaikan apa pun yang diperlukan.
Marc Gravell
Ini menyoroti titik gesekan lain dari serialisasi: Anda harus memberikan konstruktor default.
Hans Malherbe
0

Elemen kloning dalam array bukanlah sesuatu yang bisa dilakukan secara universal. Apakah Anda ingin kloning mendalam atau salinan sederhana dari semua anggota?

Mari kita pergi untuk pendekatan "upaya terbaik": objek kloning menggunakan antarmuka ICloneable atau serialisasi biner:

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

Ini bukan solusi yang sempurna, karena tidak ada satu pun yang akan bekerja untuk semua jenis objek.

Philippe Leybaert
sumber
Bukankah itu seperti hasil [i-index] = (T) ...?
Donald Byrd
ya :) Dan tidak hanya itu. Batas lingkaran salah. Saya akan memperbaikinya. Terima kasih!
Philippe Leybaert
0

Anda dapat mengambil kelas yang dibuat oleh 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;
    }
}

lalu

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
sumber
0

Ini adalah cara optimal, saya temukan, untuk melakukan ini:

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

Semoga Itu Membantu!

OscarMas
sumber
0

gunakan metode extention:

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

dan kamu bisa menggunakannya

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

Kode dari 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
sumber
0

Itu tidak memenuhi persyaratan kloning Anda, tetapi tampaknya lebih sederhana daripada banyak jawaban untuk dilakukan:

Array NewArray = new ArraySegment(oldArray,BeginIndex , int Count).ToArray();
Pak Boy
sumber
-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
sumber