使用其他数组在c#中初始化多维数组

15

在C#中,可以使用常量来初始化多维数组,如下所示:

Object[,] twodArray = new Object[,] { {"00", "01", "02"}, 
                                      {"10", "11", "12"},
                                      {"20", "21", "22"} };

我个人认为使用硬编码常量初始化数组除了测试练习以外没有什么用处。无论如何,我迫切需要做的是使用现有的数组来初始化新的多维数组(这些数组具有相同的项数,但内容当然只在运行时定义)。

我想要实现的示例是:

Object[] first  = new Object[] {"00", "01", "02"};
Object[] second = new Object[] {"10", "11", "12"};
Object[] third  = new Object[] {"20", "21", "22"};
Object[,] twodArray = new Object[,] { first, second, third };

很遗憾,这段代码无法编译通过。有趣的是,当我尝试了

Object[,] twodArray = new Object[,] { {first}, {second}, {third} };

代码确实编译并运行了,但结果不如预期 - 一个3x3对象数组,而输出的是一个3x1的数组,其中每个元素都是一个有3个元素的数组。当出现这种情况时,我无法使用以下方式访问我的数组:

Object val = twodArray[3,3];

我必须走了:

Object val = twodArray[3,1][3];

很明显这不是期望的结果。

那么,有没有办法在不使用迭代的情况下从多个现有数组初始化这个新的二维数组?


使用 Object[] { first, second, third }; 代替 Object[,] { first, second, third }; (去除维度逗号) 是否合理?应该记录为 twoarray[3][3]。 - Emmanuel Devaux
4个回答

8
这将适用于切换到锯齿数组:
int[] arr1 = new[] { 1, 2, 3 };
int[] arr2 = new[] { 4, 5, 6 };
int[] arr3 = new[] { 7, 8, 9 };

int[][] jagged = new[] { arr1, arr2, arr3 };

int six = jagged[1][2];

编辑为了让未来读到这个帖子的人更加清楚,

上面的代码示例也是不够充分的,因为它会产生一个数组的数组(object[object[]])而不是一个交错数组(object[][]),虽然它们在概念上是相同的,但却是不同的类型。


我意识到数组的数组是可能的,但每一行中有相等数量的项目,因此我真正需要的是一个二维数组结构。多维数组创建了一个漂亮的线性内存布局,而不规则数组则意味着几个额外的间接级别。 - Alain
1
另外,为了记录,我尝试了 int[][] jagged = new[] { arr1, arr2, arr3 }; 但是得到的是一个int[3][](第二维未初始化),而前三个元素都是数组。最好还是直接使用int[] jagged = new[] { arr1, arr2, arr3 }; - Alain
公正的观点,如果是这样的话,答案是否定的,没有一种方式可以仅使用数组初始化语法来初始化多维数组 :( - MattDavey
@Alain,使用这种基于集合的编程方式,你可能会发现像F#这样的函数式语言更适合你的需求 :) - MattDavey
从数组消费者的角度来看,概念上是相同的东西。而且,数组中的数组可以包含不同长度的数组... 在C#中,不规则的“数组”通常被实现为arr[a, b]。 - Arek Bal

1

您正在尝试将数组引用分配给数组。有关更多详细信息,请阅读 - 不规则数组。

请尝试这个,

Object[] first = new Object[] { "00", "01", "02" };
Object[] second = new Object[] { "10", "11", "12" };
Object[] third = new Object[] { "20", "21", "22" };
Object[][] result = { first, second, third };

foreach (object [] ar in result)
   {
       foreach (object ele in ar)
        {
            Console.Write(" " + ele);
          }
       Console.WriteLine();
   }

0

我很难完全理解你真正想要实现什么。如果我理解正确,你有一些字符串的“列表”,需要将它们存储在另一个列表中。

首先,我建议你使用比数组更现代化的方法。C#为你提供了IEnumerable<>和IList<>接口以及所有从它们派生的东西,所以不需要坚持旧式的数组。

你可以像这样做:

var list1 = new List<string> { "foo1", "foo2", "foo3" };
var list2 = new List<string> { "foo4", "foo5", "foo6" };
var list3 = new List<string> { "foo7", "foo8", "foo9" };
var listOfStrings = new List<List<string>> { list1, list2, list3 };

如果你想访问 "foo6",你可以这样写:

var temp = listOfStrings[1][2];

1
自从什么时候开始数组就过时了?在.NET中,几乎所有的集合类都只是装饰过的数组。 - MattDavey
我以字符串作为示例。我正在尝试组合一个二维对象数组,而不是一个一维数组的数组。 - Alain

0

以下代码完美运行:

var a = new object[] { 0, 1, 1, 2 };
var b = new object[] { "0", "5", "0", "0" };
var c = new object[] { true, true, true, false };

object[][] m = new object[][] { a, b, c };


 var two = m[0][3];
 var bar = m[1][1];
 var f = m[2][3];


将近十年的问题。那么,你的回答与被接受的回答有什么区别? - gurkan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接