c#数组函数参数传递一个维度

时间:2009-04-24 13:08:52

标签: c# .net arrays .net-3.5

假设我有这个功能:

void int Calculate(double[] array) {}

在我的主要部分,我得到了这个数组:

double[,] myArray = new double[3,3];

如何调用Calculate(...)?

我尝试(不编译):

double[] mySingleArray = myArray[0];

我想避免的是不必要的循环(for)。

我声明了一个常规数组,但是如果锯齿状数组或任何其他类型的数组效果更好,那对我来说没问题。

我使用c#3.5

4 个答案:

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