C #의 배열 조각 byte[4096]; 배열의 첫 x 바이트를 별도의

어떻게합니까? 바이트 배열이 주어지면 :

byte[] foo = new byte[4096];

배열의 첫 x 바이트를 별도의 배열로 얻는 방법은 무엇입니까? (구체적으로 필요합니다 IEnumerable<byte>)

Sockets 로 작업하기위한 것 입니다. 가장 쉬운 방법은 Perls 구문과 비슷한 배열 슬라이싱입니다.

@bar = @foo[0..40];

처음 41 개의 요소를 @bar배열 로 반환합니다 . C #에 방금 놓친 것이 있습니까? 아니면 다른 일이 있습니까?

LINQ는 나에게 도움이되는 옵션입니다 (.NET 3.5).



답변

배열은 열거 가능하므로 foo이미 IEnumerable<byte>자체입니다. LINQ 시퀀스 메소드를 사용하여 Take()원하는 것을 얻으십시오 ( Linq네임 스페이스 를로 포함하는 것을 잊지 마십시오 using System.Linq;).

byte[] foo = new byte[4096];

var bar = foo.Take(41);

어떤 IEnumerable<byte>값 에서든 배열이 정말로 필요하다면 그 ToArray()방법을 사용할 수 있습니다 . 그것은 사실이 아닌 것 같습니다.


답변

사용할 수 있습니다 ArraySegment<T>. 배열을 복사하지 않으므로 매우 가볍습니다.

string[] a = { "one", "two", "three", "four", "five" };
var segment = new ArraySegment<string>( a, 1, 2 );


답변

배열 CopyTo()방법을 사용할 수 있습니다 .

또는 LINQ와 함께 당신이 사용할 수있는 Skip()Take()

byte[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
var subset = arr.Skip(2).Take(2);


답변

static byte[] SliceMe(byte[] source, int length)
{
    byte[] destfoo = new byte[length];
    Array.Copy(source, 0, destfoo, 0, length);
    return destfoo;
}

//

var myslice = SliceMe(sourcearray,41);


답변

C # 8.0 / .Net Core 3.0부터

새로운 유형 IndexRange추가 되는 배열 슬라이싱이 지원 됩니다.

범위 구조 문서
색인 구조 문서

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 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"

var slice = a[i1..i2]; // { 3, 4, 5 }

위의 코드 샘플은 C # 8.0 블로그 에서 가져 왔습니다 .

점을 유의 ^접두사부터 카운트를 나타내는 최종 배열. 문서 예제에 표시된대로

var words = new string[]
{
                // index from start    index from end
    "The",      // 0                   ^9
    "quick",    // 1                   ^8
    "brown",    // 2                   ^7
    "fox",      // 3                   ^6
    "jumped",   // 4                   ^5
    "over",     // 5                   ^4
    "the",      // 6                   ^3
    "lazy",     // 7                   ^2
    "dog"       // 8                   ^1
};              // 9 (or words.Length) ^0

Range그리고 Index또한 루프를 예를 들어, 슬라이스 배열의 외부 작업

Range range = 1..4;
foreach (var name in names[range])

항목 1-4를 반복합니다.


이 답변을 작성할 당시 C # 8.0은 아직 공식적으로 릴리스되지 않은
C # 8.x이며 .Net Core 3.x는 Visual Studio 2019 이상에서 사용할 수 있습니다.


답변

에서 C # 7.2 , 당신은 사용할 수 있습니다 Span<T>. 새로운 System.Memory시스템 의 장점은 데이터를 복사 할 필요가 없다는 것입니다.

필요한 방법은 Slice다음과 같습니다.

Span<byte> slice = foo.Slice(0, 40);

방법의 많은 지금 지원 Span하고 IReadOnlySpan는이 새로운 유형을 사용하는 것은 매우 간단합니다, 그래서.

작성 당시 Span<T>유형은 최신 버전의 .NET (4.7.1)에 아직 정의되어 있지 않으므로이를 사용하려면 NuGet 에서 System.Memory 패키지 를 설치해야합니다 .


답변

내가 여기에 언급하지 않은 또 다른 가능성 : Buffer.BlockCopy ()는 Array.Copy ()보다 약간 빠르며 프리미티브 배열에서 즉석에서 변환 할 수 있다는 추가 이점이 있습니다 (예 : 짧음 [])를 바이트 배열로 변환하면 소켓을 통해 전송해야하는 숫자 형 배열이있을 때 편리합니다.