C#交错数组详说
C#的Jagged Arrays ,有的资料翻译为可变数组(原因可能是因为JaggeArrays元素的维度和大小可以不同),微软官方中文名为交错数组。
它是一个以元素为数组的数组,又称为数组的数组。为什么这么说?
因为交错数组的元素是一个数组对象。(其实只要真的明白这句话就够了。接下来的内容完全是废话,可以不看)
它的长度等于它的直接元素的个数而不是元素的子元素的个数。
举个例子,声明一个二维数组 :
int[,] nums = { { 1, 2 }, { 3, 4} };
nums.Lenght == 4,而如果nums是这样的交错数组的话:
int[][] nums = { new int[]{1,2} , new{3,4} };
看上去貌似元素都一样,都是数字,但是其实,他的元素是一维数组对象,其元素总数是2。nums.Lenght==2,而不是4。(Array.Lenght表示数组所有维度中元素的总数)
因此可以说,交错数组是一维数组。一种有点奇葩的一维数组。
交错数组还可以这样初始化:
int[][] jaggedArray = new int[2][];
jaggedArray[0] = new int[2];//长度为2的一维数组
jaggedArray[1] = new int2];//长度为2的一维数组
当然,这样初始化后一维数组(元素)的元素的默认值是0;
或者直接赋值填充:
jaggedArray[0] = new int[] { 1, 2 };
jaggedArray[1] = new int[] { 3, 4 };
以上示例的交错数组元素的元素长度都是2,并没有体现出“交错数组元素的维度和大小可以不同”的特性(双引号内微软说的)。因为这句话并不意味着,交错数组在初始化时元素可以是一维数组和二维数组同时存在。这种东西并不存在:
jaggeArray = new int[][]{
new int[]{1,2},
new int[,]{{1,2},{3,4}}
};
因为 new int[][] 第二个[]指明了其中的元素是一维数组,所以其元素只能是一维数组,混进了二维、三维的数组会直接报错。
其维度的不同,只是意味着可以全是一维数组,或全是二维数组,而因为不同数组大小可能不同,所以,元素的大小可以不同。(交错数组的元素就是数组)
那么,既然交错数组的元素的维度和大小可以不同,所以,就可以有元素是二维,三维,四维的交错数组了。
三维,四维往上太麻烦,太可怕,所以以元素是二维数组的交错数组来举例。
声明并初始化一个元素是二维数组的交错数组:
int[][,] jaggeArray = new int[][,]{
new int[,]{{1,2},{2,3}},
new int[,]{{3,4},{4,5}},
new int [,]{{4,5},{5,6},{6,7}}
};
当然,也可以麻烦一些,一个一个元素的赋值和new。
jaggeArray = new int[3][,];
jaggeArray[0] = new int[,] { { 1, 2 }, { 2, 3 } };
jaggeArray[1] = new int[,] { { 3, 4 }, { 4, 5 } };
jaggeArray[2] = new int[,] { { 4, 5 }, { 5, 6 }, { 6, 7 } };
或者更麻烦的:
//new交错数组
jaggeArrayelse ( = new int[3][,];
//new交错数组的每个元素
jaggeArrayelse ([0] = new int[2,2] ;
jaggeArrayelse ([1] = new int[2,2];
jaggeArrayelse ([2] = new int[3,2];
//为第一个元素的元素赋值
jaggeArrayelse ([0][0, 0] = 1;
jaggeArrayelse ([0][0, 1] = 2;
jaggeArrayelse ([0][1, 0] = 2;
jaggeArrayelse ([0][1, 1] = 3;
//为第二个元素的元素赋值
jaggeArrayelse ([1][0, 0] = 3;
jaggeArrayelse ([1][0, 1] = 4;
jaggeArrayelse ([1][1, 0] = 4;
jaggeArrayelse ([1][1, 1] = 5;
//为第三个元素的元素赋值
jaggeArrayelse ([2][0, 0] = 4;
jaggeArrayelse ([2][0, 1] = 5;
jaggeArrayelse ([2][1, 0] = 5;
jaggeArrayelse ([2][1, 1] = 6;
jaggeArrayelse ([2][2, 0] = 6;
jaggeArrayelse ([2][2, 1] = 7;
这种写法绝对是得不偿失啊。所以还是这么初始化好使:
int[][,] jaggeArray = new int[][,]{
new int[,]{{1,2},{2,3}},
new int[,]{{3,4},{4,5}},
new int [,]{{4,5},{5,6},{6,7}}
}
;
当然超级麻烦的写法其实也是有应用场景的,那就是在修改或者赋值给交错数组的某个元素的某个子元素的值的时候。而通常初始化数据则不必这么神烦。
至于交错数组的遍历,其实和二维数组也差不多。foreach和普通for都可以,只是forecah写法简单,但不如普通for灵活,更好控制,而普通for写法有点复杂,坑烦。
最后附上完整测试代码,包括二维数组,交错数组的遍历等:
ArrayTest.cs:
using System;
using System.Reflection;
using System.Text;
namespace Shape
{
/// <summary>
/// 数组测试
/// </summary>
public class ArrayTest
{
/// <summary>二维数组</summary>
string[,] colorsStr = {
{ "#ff0000", "黄" },
{ "#00ff00", "绿" },
{ "#0000ff", "蓝" }
};
/// <summary> 字符数组 </summary>
char[] chars = new char[5];
//可变数组的行数固定,列数不像二维数组那样全部固定为同一个值
//比如第一行,可以有三列,第二行有两列。
//int[2][] nums = { {1,2,3} , {1,2} }
/// <summary>交错数组1</summary>
int[][] jaggeArray_1 = new int[3][];
/// <summary>交错数组2</summary>
int[][,] jaggeArray_2;
public ArrayTest()
{
colorsStr[0, 1] = "红";
chars[0] = "我";
chars[1] = "是";
chars[2] = "字";
chars[3] = "符";
chars[4] = "型";
//chars[5] = "。";
//直接将数组的值赋给第一、第二行
jaggeArray_1[0] = new int[] { 1 };
jaggeArray_1[1] = new int[] { 1, 2 };
jaggeArray_1[2] = new int[3];
//分别为第三行赋值
jaggeArray_1[2][0] = 1;
jaggeArray_1[2][1] = 2;
jaggeArray_1[2][2] = 3;
//交错数组混合二维数组,交错数组长度为3,每个二维数组都是其中一个元素(对象)
//jaggeArray_2 = new int[][,]{
// new int[,]{{1,2},{2,3}},
// new int[,]{{3,4},{4,5}},
// new int [,]{{4,5},{5,6},{6,7}}
// };
//new交错数组
jaggeArray_2 = new int[3][,];
//new交错数组的每个元素
jaggeArray_2[0] = new int[2,2] ;
jaggeArray_2[1] = new int[2,2];
jaggeArray_2[2] = new int[3,2];
//为第一个元素的元素赋值
jaggeArray_2[0][0, 0] = 1;
jaggeArray_2[0][0, 1] = 2;
jaggeArray_2[0][1, 0] = 2;
jaggeArray_2[0][1, 1] = 3;
//为第二个元素的元素赋值
jaggeArray_2[1][0, 0] = 3;
jaggeArray_2[1][0, 1] = 4;
jaggeArray_2[1][1, 0] = 4;
jaggeArray_2[1][1, 1] = 5;
//为第三个元素的元素赋值
jaggeArray_2[2][0, 0] = 4;
jaggeArray_2[2][0, 1] = 5;
jaggeArray_2[2][1, 0] = 5;
jaggeArray_2[2][1, 1] = 6;
jaggeArray_2[2][2, 0] = 6;
jaggeArray_2[2][2, 1] = 7;
}
public static ArrayTest newInstance()
{
return new ArrayTest();
}
public void testGo()
{
colorTest();
numTest();
}
private void numTest()
{
Console.WriteLine("遍历交错数组1:");
foreach (var item in jaggeArray_1)
{
StringBuilder sb = new StringBuilder();
foreach (int num in item)
{
sb.Append(num + " ");
}
Console.WriteLine(sb);
}
Console.WriteLine("交错数组长度:" + jaggeArray_2.Length);
Console.WriteLine("遍历交错数组2:");
for (int i = 0; i < jaggeArray_2.Length; i++)
{
int[,] items = jaggeArray_2[i];
Console.WriteLine("交错数组第" + i + "个元素(二维数组)的长度:" + items.Length);
for (int j = 0; j < items.GetLength(0); j++)
{
for (int k = 0; k < items.GetLength(1); k++)
{
Console.WriteLine(items[j, k]);
}
}
}
}
private void colorTest()
{
for (int i = colorsStr.GetLowerBound(0); i < colorsStr.GetUpperBound(0) + 1; i++)
{
StringBuilder str = new StringBuilder();
for (int j = colorsStr.GetLowerBound(1); j < colorsStr.GetUpperBound(1) + 1; j++)
{
str.Append(colorsStr[i, j]);
}
Console.WriteLine(str);
}
}
}
}
在main方法中调用即可:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shape
{
class Test
{
static void Main(string[] args)
{
ArrayTest.newInstance().testGo();
Console.ReadLine();
}
}
}
- 上一篇: 二维数组与交错数组
- 下一篇: C#中交错数组的初始化