假设我有这个功能:
void int Calculate(double[] array) {}
在我的主要部分,我得到了这个数组:
double[,] myArray = new double[3,3];
如何调用Calculate(...)?
我尝试(不编译):
double[] mySingleArray = myArray[0];
我想避免的是不必要的循环(for)。
我声明了一个常规数组,但是如果锯齿状数组或任何其他类型的数组效果更好,那对我来说没问题。
我使用c#3.5
答案 0 :(得分:6)
首先,让我们像这样声明你的Calculate()方法:
int Calculate(IEnumerable<double> doubles)
别担心,您仍然可以将数组传递给该代码。您可能还需要IList<double>
,但是10个中有9个IEnumerable足够好。最重要的是,这将让我们使用yield
关键字以有效的方式切割您的数组:
public static IEnumerable<T> Slice(this T[,] values)
{
return Slice(values, 0, 0);
}
public static IEnumerable<T> Slice(this T[,] values, int index)
{
return Slice(values, 0, index);
}
public static IEnumerable<T> Slice(this T[,] values, int dimension, int index)
{
int length = values.GetUpperBound(dimension);
int[] point = new int[values.Rank];
point[dimension] = index;
dimension = 1 - dimension;// only works for rank == 2
for (int i = 0; i < length; i++)
{
point[dimension] = i;
yield return (T)values.GetValue(point);
}
}
它仍然需要一些工作,因为它只适用于2级数组,但对于您发布的示例应该没问题。
现在你可以像这样调用你的计算函数:
Calculate(myArray.Slice(0));
请注意,由于IEnumerable和yield语句的工作方式,我发布的代码中的for循环基本上是免费的。它直到您实际迭代Calculate方法中的项目才会运行,甚至以“即时”方式运行,以便整个算法保持为O(n)。
当您分享您的Calculate方法正在执行的操作时,它会变得更加有趣。您可以将其表达为简单的Aggregate + lambda表达式。例如,假设您的计算方法返回了项目数&gt; 5:
myArray.Slice(0).Count(x => x > 5);
或者说它总结了所有项目:
myArray.Slice().Sum();
答案 1 :(得分:4)
锯齿状阵列的工作方式如下:
double[][] jaggedArray = new double[][100];
for (int i = 0; i < jaggedArray.Length; ++i)
jaggedArray[i] = new double[100];
myFunction(jaggedArray[0]);
您可以通过这种方式为每个阵列设置不同的大小。
答案 2 :(得分:0)
锯齿状阵列可以让你拆分掉第一个数组!
答案 3 :(得分:0)
上面给出的Slice()方法会从你的数组中获得一行,它似乎与你问题中给出的样本相匹配。
但是,如果你想要一个包含 all 矩形数组中元素的一维数组,你可以使用这样的东西,也就是O(n)。
public static T[] Flatten<T>(this T[,] array)
where T : struct
{
int size = Marshal.SizeOf(array[0, 0]);
int totalSize = Buffer.ByteLength(array);
T[] result = new T[totalSize / size];
Buffer.BlockCopy(array, 0, result, 0, totalSize);
return result;
}