2024-04-14 06:00:02

c#中的数组片

你是怎么做到的?给定一个字节数组:

byte[] foo = new byte[4096];

我如何得到数组的前x字节作为一个单独的数组?(具体来说,我需要它作为一个IEnumerable<byte>)

这是用于使用Sockets的。我认为最简单的方法是数组切片,类似于perl语法:

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

将前41个元素返回到@bar数组中。c#中是否有我遗漏的东西,或者有其他我应该做的事情?

LINQ对我来说是一个选择。NET 3.5),如果有帮助的话。


当前回答

如果你不想添加LINQ或其他扩展,只需:

float[] subArray = new List<float>(myArray).GetRange(0, 8).ToArray();

其他回答

可以使用数组的CopyTo()方法。

或者使用LINQ,你可以使用Skip()和Take()…

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

数组是可枚举的,所以你的foo已经是IEnumerable<字节>本身。 简单地使用像Take()这样的LINQ序列方法来获得你想要的结果(不要忘记在使用System.Linq;时包含LINQ命名空间):

byte[] foo = new byte[4096];

var bar = foo.Take(41);

如果你真的需要一个来自任何IEnumerable<byte>值的数组,你可以使用ToArray()方法。但在这里,情况似乎并非如此。

下面是一个使用泛型的扩展函数,其行为类似于PHP函数array_slice。允许负偏移量和负长度。

public static class Extensions
{
    public static T[] Slice<T>(this T[] arr, int offset, int length)
    {
        int start, end;

        // Determine start index, handling negative offset.
        if (offset < 0)
            start = arr.Length + offset;
        else
            start = offset;

        // Clamp start index to the bounds of the input array.
        if (start < 0)
            start = 0;
        else if (start > arr.Length)
            start = arr.Length;

        // Determine end index, handling negative length.
        if (length < 0)
            end = arr.Length + length;
        else
            end = start + length;

        // Clamp end index to the bounds of the input array.
        if (end < 0)
            end = 0;
        if (end > arr.Length)
            end = arr.Length;

        // Get the array slice.
        int len = end - start;
        T[] result = new T[len];
        for (int i = 0; i < len; i++)
        {
            result[i] = arr[start + i];
        }
        return result;
    }
}

我不认为c#支持范围语义。你也可以写一个扩展方法,比如:

public static IEnumerator<Byte> Range(this byte[] array, int start, int end);

但就像其他人说的,如果你不需要设置一个开始索引,那么Take就是你所需要的。

你可以使用ArraySegment<T>。它非常轻量级,因为它不复制数组:

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