我想问一下如何在不使用Array.Copy的情况下切片数组。 我会给你一个我想要实现的例子,这样你就能理解我。
假设我有这个数组。叫原文
[1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15]
我想从给定长度的起始索引中获取一个副本数组,让我说我想要元素一到元素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
,当循环中的i得到值13时,它会抛出OutOfBoundsException
,它会尝试复制不存在的数组[15]。我想避免这些错误。
我正在开发Winforms,.Net 4.0
答案 0 :(得分:8)
我认为处理您的方法的最佳方法是使用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);
我在记事本中写道,所以我可能会错过一些小事,但这应该可以满足您的需求。如果它始终为0,则可以跳过.Skip(startIndex)部分。要访问每个int:
foreach (int value in CopyArray) {
// TODO with value??
}
答案 1 :(得分: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}
和{15}
。
答案 2 :(得分: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;
}
}
}