6

我想问如何在不使用 Array.Copy 的情况下对数组进行切片。我会给你一个我想要实现的例子,这样你就可以理解我了。

假设我有这个数组。称为原始

[ 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15]

我想从给定长度的起始索引中获取一个副本数组,假设我想要元素 1 到元素 6 我想要代码执行任务,例如

int startIndex = 0;
int lenght= 5;
int[] CopyArray = ArrayFromRange(Original, startIndex, length);

那么 copyArray 将是:

[ 1 | 2 | 3 | 4 | 5] 我不想使用 Array.Copy 因为我会循环它来获取后续切片

所以我会做

int length = 3;
for(int i = 0; i < OriginalArray.Length; i++)
{
     int[] CopyArray = ArrayFromRange(OriginalArray, i, length);
     // perform some operations
}

每次循环执行它时,这会给我一个包含 4 个元素的数组,然后我会做一些操作。但如果我这样做Array.Copy了,它会抛出一个OutOfBoundsException错误,它会尝试复制不存在的数组 [15]。我想避免这些错误。

我正在开发 Winforms,.Net 4.0

4

3 回答 3

9

我认为处理您的方法的最佳方法是使用 IEnumerable 对象,特别是使用 LINQ。IEnumerable 是一个接口,意思是“你可以在这个对象上调用 foreach”。它适用于数组,也适用于用于查询集合的其他一些对象——部分原因是,您不需要特别知道这些对象是什么;只需在需要时枚举每个项目。

using System.Linq; // put this at the top of the .cs, not mid-code.

int startIndex = 0;
int lenght= 5;
IEnumerable<int> CopyArray = Original.Skip(startIndex).Take(lenght);

我在记事本中写了这个,所以我可能遗漏了一些小东西,但这应该会给你你需要的东西。如果 .Skip(startIndex) 部分始终为 0,则可以跳过它。要访问每个 int:

foreach (int value in CopyArray) {
   // TODO with value??
}
于 2013-07-06T01:50:42.350 回答
1

您仍然可以使用Array.Copy(),但您只需要确保索引在范围内:

T[] ArrayFromRange<T>(T[] originalArray, int startIndex, int length)
{
  int actualLength = Math.Min(length, originalArray.Length - startIndex);
  T[] copy = new T[actualLength];
  Array.Copy(originalArray, startIndex, copy, 0, actualLength);
  return copy;
}

在您的示例中,循环中的最后两个数组是{14,15}and {15}

于 2013-07-06T01:57:31.773 回答
0

如果您更喜欢返回缩短数组的方法,我可以提供其中之一,但我假设这是您想要的:(是的,这已经过测试)

using System;
namespace ArraySlice
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] array1 = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
            byte[] array2 = GetSlice<byte>(array1, 5, 10);
            for (int i = 0; i < array2.Length; i++)
            {
                Console.WriteLine(array2[i]);
            }
            Console.ReadKey();
        }
        static T[] GetSlice<T>(T[] array, int start, int length)
        {
            T[] result = new T[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = ((start + i) < array.Length) ? array[start + i] : default(T);
            }
            return result;
        }
    }
}
于 2013-07-06T02:07:04.653 回答