正确的形式在C#中切片数组

时间:2013-07-06 01:40:33

标签: c# arrays

我想问一下如何在不使用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

3 个答案:

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