锯齿数组:
二维数组的大小对应于一个矩形,如对应元素为3X3.
锯齿数据的大小设置比较灵活,在锯齿数组汇总,每一行都可以有不同的大小。
在声明锯齿数组时,要依次放置左右括号。左括号要设置该数组包含的行数。定义
各行中元素个数的右方括号设置为空,因为这样可以为每一行指定行中的元素个数:
int[][] jagged=new int[3][]; jagged[0]=new int[2]{1,2}; jagged[1]=new int[6]{3,4,5,6,7,8}; jagged[2]=new int[3]{9,10,11};
迭代锯齿数组中所有元素的代码可以放在嵌套for循环中。在外层的for循环中迭代每一行。
在内层的for循环中迭代每一行中的元素。
for(int row=0;row<jagged.length;row++) { for(int element=0;element<jagged[row].Length;element++) { Console.WriteLine($"row:{row}.element:{element},value:{jagged[row][element]}") } }
C#中的排序算法都是使用快速排序(Quicksort)算法来进行排序.Sort()方法需要数组中的元素实现IComparable接口。简单类型(内置的值类型和string[有其他在补充])实现了IComparable接口。
如果对数组使用自定义类,就必须实现IComparable接口。这个接口只定义一个方法CompareTo(),
如果要比较对象相等,该方法就返回0。如果 A和B 比较 小于零的话A排在B前面。如果大于零,则B排在A前面。
string.Compare(string a,string b) >0 b,a
string.Compare(string a,string b) <0 a,b
如果Person对象的排序方式于上述不同,或者不能修改在数组中用作元素的类,就可以实现
IComparer接口或者IComparer<T>接口。这两个接口定义了方法Compare()。
要比较的类必须实现者两个接口之一。
public class PersonComparer:IComparer<Person> { private readonly PersonCompareType _personCompareType; public PersonComparer(PersonCompareType personCompareType) { _personCompareType = personCompareType; } public int Compare(Person x, Person y) { if (x == null && y == null) return 0; if (x == null) return 1; if (y == null) return -1; switch (_personCompareType) { case PersonCompareType.FirstName: return string.CompareOrdinal(x.FirstName, y.FirstName); case PersonCompareType.LastName: return string.CompareOrdinal(x.LastName, y.LastName); default: throw new ArgumentException("unexpercted compare type"); } } } public enum PersonCompareType { FirstName, LastName }
Main
Person[] persons = { new Person { FirstName = "Damon", LastName = "Hill" }, new Person { FirstName = "Niki", LastName = "Lauda" }, new Person { FirstName = "Ayrton", LastName = "Senna" }, new Person { FirstName = "Graham", LastName = "Hill" }, }; Array.Sort(persons, new PersonComparer(PersonCompareType.LastName)); foreach (var item in persons) { Console.WriteLine($"{item.FirstName} {item.LastName}"); }
Array类的Sort方法,他需要将一个委托作为参数。这个参数可以传递给方法,从而比较两个对象,而不需要依赖于IComparable和IComparer接口。
数组协变
数组支持协变。表示数组可以声明为基类,其派生类型的元素可以赋予数组元素。
例如声明一个Object[]类型参数,给他传递一个Person[]:
数组协变只能用于引用类型,不能用于值类型。数组协变有一个问题,它只能通过运行时异常来解决。
ArraySegment<T>
结构ArraySegment<T>表示数组的一段。如果需要使用不同的方法处理某个大型数组的不同部分。那么可以把相应的数组部分复制到各个方法中。此时,于创建多个数组相比,更有效的方法是使用一个数组,将整个数组传递给不同的方法。方法的参数除了数组以外,还应包括数组内的偏移量和该方法使用的元素数。
static int SumofSeqments(ArraySegment<int>[] segments) { int sum = 0; foreach (var segment in segments) { for (int i = segment.Offset; i < segment.Offset+segment.Count; i++) { sum += segment.Array[i]; } } return sum; }
Main
int[] arr1 = {1, 4, 5, 11, 13, 18}; int[] arr2 = {3, 4, 5, 18, 21, 27, 33}; var segments = new ArraySegment<int>[2] { new ArraySegment<int>(arr1, 0, 3), new ArraySegment<int>(arr2, 3, 3) }; var sum = SumofSeqments(segments); //1+4+5 18+21+33 Console.WriteLine(sum);