기존 배열에서 하위 배열 얻기


335

10 개의 요소로 구성된 배열 X가 있습니다. 인덱스 3에서 시작하여 인덱스 7로 끝나는 X의 모든 요소를 ​​포함하는 새 배열을 만들고 싶습니다. 물론 나를 위해 할 루프를 쉽게 작성할 수 있지만 가능한 한 코드를 깨끗하게 유지하고 싶습니다. . C #에 나를 위해 할 수있는 방법이 있습니까?

(의사 코드)와 같은 것 :

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

Array.Copy내 요구에 맞지 않습니다 . 새 배열의 항목이 복제본이 필요합니다. Array.copyC 스타일 memcpy과 동일하며 내가 찾고있는 것이 아닙니다.



7
@Kirtan- "dup"은 IEnumerable <T>을 원합니다. 이는 다르고 최적의 솔루션이 다릅니다. IMO
Marc Gravell

따라서 새 배열을 선언하고 .Copy ()를 호출하는 데 필요한 두 줄이 "깨끗한 코드"가 아닙니까?
Ed S.

2
@Ed Swangren - 아니 당신이 연쇄 식의 중간에 그것을 할 필요가 있다면, 더 ;-p 없습니다
마크 Gravell

2
ShaggyUk의 답변은 아마도 정답 일 것입니다 : stackoverflow.com/questions/943635/…
Dykam

답변:


469

확장 방법으로 추가 할 수 있습니다.

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

다시 복제 업데이트 (원래 질문에서 명확하지 않음). 당신이 정말로 깊은 클론을 원한다면; 같은 :

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

그러나 객체를 직렬화 가능 ( [Serializable]또는 ISerializable) 해야합니다 . - 당신은 쉽게 적절한 다른 직렬에 대한 대체 할 수 XmlSerializer, DataContractSerializer등, protobuf - 그물,

딥 클론은 직렬화없이 까다로울 수 있습니다. 특히 ICloneable대부분의 경우 신뢰하기가 어렵습니다.


1
(길이가 아닌 종료 인덱스를 사용하는 것은 간단한 변화입니다. 더 일반적인 경우가 많기 때문에 "있는 그대로"게시했습니다)
Marc Gravell

1
그렇다면 ... 힘든; 그렇게하지 않습니다. .... 비슷한 것을 달성하기 위해 직렬화를 사용해야 할 것입니다.
Marc Gravell

1
일부 대안에 대한 내 대답과 여러 구현에 대한 링크를 참조하십시오. 하위 배열에 대한 부분은 실제로 사소한 것입니다. 실제로 원하는 것은 복제 비트이며 이는 '올바른'행동 에 대한 기대에 전적으로 의존하는 복잡하고 다소 열린 질문입니다 .
ShuggyCoUk

2
이거 좋은데. 그리고 ICloneable이 신뢰할 수 없음을 지적하는 것이 특히 좋습니다.
마커스 그리프

1
C #에서 딥 클로닝 문제를 강조해 주셔서 감사합니다. 딥 카피는 기본 작업이므로 정말 부끄러운 일 입니다.
Dimitri C.

316

당신은 사용할 수 있습니다 Array.Copy(...)당신이 그것을 만든 후 새 배열에 복사,하지만 난 새로운 배열을 생성하는 방법이 생각하지 않습니다 사본 요소의 범위.

.NET 3.5를 사용하는 경우 LINQ를 사용할 있습니다.

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

그러나 그것은 다소 덜 효율적입니다.

보다 구체적인 상황에 대한 옵션에 대해서는 유사한 질문에 대한 이 답변 을 참조하십시오 .


+1이 변형도 좋아합니다. 존, 왜 이것이 덜 효율적이라고 여겨 질 수 있습니까?
Ian Roke

@Jon : 질문에 맞추기 위해 "Take (5)"가 아니겠습니까? @Ian : Array.Copy 접근 방식에는 열거자가 포함되지 않으며 대부분 직선형 Memcopy가 될 것입니다.
Marc Gravell

@Marc : 그렇습니다. 너무 많은 질문 감추기 :)
Jon Skeet

11
@Ian : LINQ 방식은 두 가지 수준의 간접 (반복자)를 도입하고 명시 적으로 항목을 건너 뛰어야하며 최종 배열이 얼마나 큰지 알지 못합니다. 2 백만 요소 배열의 후반부를 고려해보십시오. 간단한 "대상 배열 작성, 복사"접근 방식은 다른 요소를 건드리지 않고 필요한 블록을 한 번에 복사합니다. LINQ 접근 방식은 배열이 시작점에 도달 할 때까지 배열을 통과 한 다음 값을 가져 오기 시작하고 버퍼를 작성합니다 (버퍼 크기 증가 및 주기적 복사). 훨씬 덜 효율적입니다.
Jon Skeet

5가 EndIndexm이면 올바른 질문은 array.Skip (3) .Take (5-3 + 1) .ToArray (); 즉. array.Skip (StartIndex) .Take (EndIndex-StartIndex + 1) .ToArray ();
Klaus78

73

ArraySegment? 사용을 고려 했습니까 ?

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


1
아마도 원하는 것을하지만 기본 배열 구문을 지원하지 않거나 IEnumerable을 지원하지 않으므로 특히 깨끗하지 않습니다.
Alex Black

5
더 많은 투표가 필요합니다. 내 경험상 ArraySegment 복사도 약간 더 빠릅니다 (
결론

5
@AlexBlack .NET 4.5 와 유사 하게 구현 IEnumerable<T>되며 다양한 기타 유용한 인터페이스를 구현 합니다.
pswg

1
어떻게 사용하는 것이 ArraySegment원래의 질문에 대답?
Craig McQueen

2
@CraigMcQueen-다음의 한 줄 접근을 시도하십시오 :IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
skia.heliou

36

참조를 복사하는 것이 아니라 복제를 원한다고 봅니다. 이 경우 .Select배열 구성원을 복제본에 투영 하는 데 사용할 수 있습니다 . 예를 들어, 요소가 구현 된 경우 IClonable다음과 같은 작업을 수행 할 수 있습니다.

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

참고 :이 솔루션에는 .NET Framework 3.5가 필요합니다.


이것은 더 우아합니다.
smwikipedia

이것이 바로 내가 찾던 것입니다. 이것은 어느 쪽이든 작동합니다 IEnumerable. 나는 얻을 수있다 IEnumerable, IList, IArray내가 필요 인라인 경우, 최소한의 소란 ... 등. 딥 카피가 필요하지 않으면을 제거하면 Select됩니다. 떨어 뜨리 Skip거나 Take범위를 제어 할 수 있습니다. 또는, SkipWhile및 / 또는와 섞을 수 있습니다 TakeWhile.
Mike

33

다음 코드는 한 줄로 수행합니다.

// 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();

한 줄로 Linq를 추가 할 필요가 없습니다. 내가 선호하는 방법입니다.
Dimitris 2016 년

여전히 소스를 복제하지는 않지만 어쨌든 좋은 접근 방식입니다
IG Pascual

1
ToArray : (1) 새 배열을 만들고 (2) Array.Copy를 실행하기 때문에 소스를 복제해야합니다. 결국 소스와 슬라이스는 두 개의 개별 객체입니다. 그러나이 방법은 맞습니다. Array.Copy : referencesource.microsoft.com/#mscorlib/system/collections/…를
Krauss

13

C # 8 그들은 새로운 도입했습니다 RangeIndex유형을

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 }

12
string[] arr = { "Parrot" , "Snake" ,"Rabbit" , "Dog" , "cat" };

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

8

Marc의 답변을 기반으로하지만 원하는 복제 동작 추가

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

그리고 ICloneable을 구현하는 것이 어려운 일과 비슷 하다면 Håvard Stranden의 Copyable 라이브러리 를 사용하여 많은 노력을 기울여야 합니다.

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

OX.Copyable 구현은 다음과 함께 작동합니다.

그러나 자동 사본이 작동하려면 다음 명령문 중 하나를 보유해야합니다.

  • 형식에는 매개 변수가없는 생성자가 있어야합니다. 또는
  • Copyable이거나
  • 해당 유형에 대해 IInstanceProvider가 등록되어 있어야합니다.

따라서 이것은 당신이 가진 거의 모든 상황을 다루어야합니다. 하위 그래프에 db 연결 또는 파일 / 스트림 핸들과 같은 항목이 포함 된 개체를 복제하는 경우 분명히 문제가 있지만 일반 딥 카피에는 해당됩니다.

다른 딥 카피 방법을 사용하려면이 기사에 다른 몇 가지 방법이 있으므로 직접 작성하지 않는 것이 좋습니다.


첫 번째는 아마도 복제를 요구하면서 원하는 솔루션 일 것입니다. Copy 메서드를 사용하면 메서드 자체가 이미 그렇게하는 경우 확장 메서드이므로 null을 확인할 필요조차 없습니다. 시도해 볼 가치가 있습니다.
Dykam

예, null 검사에 주목했지만 소스를 읽지 않은 경우 OP를 혼동하고 싶지 않았습니다.
ShuggyCoUk

2
참고 사항 : GitHub의 최신 Copyable 버전에는 개체에 매개 변수가없는 생성자가 필요하지 않습니다. :) github.com/havard/copyable
Håvard S

8

이 작업을 매우 쉽게 수행 할 수 있습니다.

    object[] foo = new object[10];
    object[] bar = new object[7];   
    Array.Copy(foo, 3, bar, 0, 7);  

아니요, 막대는 여전히 null입니다. Array.Copy는 마술처럼 새 배열을 만들지 않습니다. 특히 막대가 ref 또는 out으로 전달되지 않기 때문입니다.
Zr40

2
오, 야, 너의 권리, 나는 이것을 서두르지 마라. 그러나 이봐, 아마도 당신의 글을 비평 할 때 당신은 교정을해야 할 것이다. 따라서 array.copy 전에 "bar = new object [7];"
RandomNickName42

4

찾고있는 코드는 다음과 같습니다.

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


나는 내가 좋은 친구를 여기에서 만들고 있다고 생각합니다 .... 당신과 같은 대답;) 그리고 나는 많이 투표를 받았습니다! 아 !! 어쨌든, 좋은 시간 좋은 시간.
RandomNickName42

3

데이터 복사에 대한 대안으로 래퍼를 만들어 배열의 일부의 복사 본인 것처럼 원래 배열의 일부에 액세스 할 수 있습니다. 장점은 메모리에 데이터의 다른 사본을 얻지 못하고 데이터에 액세스 할 때 약간의 오버 헤드가 발생한다는 것입니다.

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

}

용법:

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

@Robert : 아뇨. 대신 ArraySegment를 사용하면 항목을 반복하지 않고 색인으로 항목에 액세스 할 수 없다는 것을 알 수 있습니다.
Guffa

2

Array.ConstrainedCopy가 작동합니다.

public static void ConstrainedCopy (
    Array sourceArray,
    int sourceIndex,
    Array destinationArray,
    int destinationIndex,
    int length
)

2
그것은 단지 데이터를 복사합니다. 새 배열 등을 만들지 않습니다. 배열이 새로운 경우 Array.Copy를 사용하면 더 효율적입니다 (추가 확인 / 롤백 필요 없음).
Marc Gravell

맞습니다. 그러나 새 배열을 만드는 것은 한 줄의 코드 일 뿐이며 새로운 방법이 필요하지 않습니다. Array.Copy도 작동한다는 데 동의합니다.
crauscher

1

원하는 것을 수행하는 단일 방법은 없습니다. 배열의 클래스에 대해 클론 메소드를 사용 가능하게해야합니다. 그런 다음 LINQ가 옵션 인 경우 :

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

class Foo
{
    public Foo Clone()
    {
        return (Foo)MemberwiseClone();
    }
}

1

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

아래는 내 원래 게시물입니다. 이거 작동 안 할거야

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

1

이건 어때요:

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;

}

그런 다음 이것을 사용해야하는 모든 클래스에서 ICloneable 인터페이스를 구현해야하지만 그렇게해야합니다.


1

나는 그것이 얼마나 깊이 있는지 확실하지 않지만,

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

약간의 오버 헤드이지만 불필요한 방법을 잘라낼 수 있습니다.


1

C # 8은 시작부터 끝까지 인덱스를 가져 오기 위해 Range라는 기능을 제공했습니다. 이렇게 사용할 수 있습니다.

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 }

그것은 미친 pythonic s ** t입니다. 나는 그것을 좋아한다.
Ch3shire

예, 정말 멋진 기능입니다
vivek nuna

0

복제가 진행되는 한 직렬화가 생성자를 호출한다고 생각하지 않습니다. ctor에서 흥미로운 일을하고 있다면 클래스 불변을 깰 수 있습니다.

복사 생성자를 호출하는 가상 클론 메소드가 더 안전한 것 같습니다.

protected MyDerivedClass(MyDerivedClass myClass) 
{
  ...
}

public override MyBaseClass Clone()
{
  return new MyDerivedClass(this);
}

직렬화가 생성자를 호출하는지 여부는 특정 직렬화기에 달려 있습니다. 어떤 사람들은 그렇지 않습니다. 그러나 일반적으로 콜백 지원을 제공하지 않는 시스템에서는 필요한 수정 작업을 수행 할 수 있습니다.
Marc Gravell

이것은 직렬화의 또 다른 마찰 점을 강조합니다. 기본 생성자를 제공해야합니다.
Hans Malherbe

0

배열에서 요소를 복제하는 것은 보편적 인 방법으로 수행 할 수있는 것이 아닙니다. 깊은 복제 또는 모든 회원의 간단한 사본을 원하십니까?

ICloneable 인터페이스 또는 이진 직렬화를 사용하여 객체 복제 :

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

이것은 모든 유형의 객체에 작동하는 것이 없기 때문에 완벽한 솔루션은 아닙니다.


결과 [i-index] = (T) ...와 같은 것이 아닌가?
Donald Byrd

예 :)뿐만 아니라. 루프 경계가 잘못되었습니다. 내가 고칠 게 감사!
Philippe Leybaert

0

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

그리고

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

0

이것이 내가 찾은 최적의 방법입니다.

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

그것이 도움이되기를 바랍니다!


0

확장 법 사용 :

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

그리고 당신은 그것을 사용할 수 있습니다

var NewArray = OldArray.Slice(3,7);

0

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



0

복제 요구 사항을 충족하지는 않지만 많은 답변보다 간단합니다.

Array NewArray = new ArraySegment(oldArray,BeginIndex , int Count).ToArray();

-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();
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.