來源:https://note.guoqianfan.com/2021/07/13/Range-and-Index-in-csharp
Range-范圍
范圍運算符
-
范圍運算符:
..,它會生成一個Range對象。 -
語法:
{startIndex}..{endIndex}:包含startIndex,不包含endIndex -
限制:0 <=
startIndex<=endIndex<=arr.Length,其他均會報錯!startIndex等於endIndex時,取不出元素,會生成一個空數組。
注意:
- 默認情況下,
..的前面是0,后面是arr.Length(不含)。..等價於0..arr.Length。 - 所以
..的前面和后面均可以為空。 - 所以
..也可以單獨使用,代表整個索引范圍(0..arr.Length):arr[..]是arr的完整拷貝。
深拷貝還是淺拷貝需要看元素是值類型還是引用類型。值類型復制值,可以認為是深拷貝;引用類型復制引用,就是淺拷貝。
Range
Range用來從集合中取出 指定索引范圍 的元素來生成新的集合。
創建Range:Range range = 2..4;
var arr = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Range range = 2..4;
int[] slice = arr[range]; // 或 arr[2..4];
foreach (var number in slice)
{// [3, 4]
Console.WriteLine(number);
}
arr[2..4]表示把arr這個序列,從索引為2的元素一直到索引為4(不含4)的元素提取出來組成新的序列。所以結果就是3,4。
Index-索引
Index用來指定索引。該索引可以用來從集合中取出指定索引處的元素,是單個元素。
乍一看,Index與int類型的索引沒啥區別。嗯。。確實是這樣,因為Index要與^操作符結合起來才能發揮更大的作用。對了,還有Range。。
末尾運算符
^是末尾運算符(Hat運算符),它會生成一個Index對象,用來從末尾開始往前取數據。
與正向取數據時索引從0開始不同,^取數據時是從1開始的,代表倒數第一個元素。
arr[^1]等於arr[arr.Length-1],最后一個元素arr[^0]等於arr[arr.Length],常與Range組合使用
如果使用arr[^0]的話就會拋出IndexOutOfRangeException,arr[^0]和arr[arr.Length]是一個意思。
這確實有點容易讓人混淆,但其實其它語言也差不多是這樣設計的,例如-1這個索引表示最后一個元素。
組合使用 Range 和 Index
完整拷貝數組的3種方式
int[] arr = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] arr01 = arr[0..arr.Length];
int[] arr02 = arr[0..^0];
int[] arr03 = arr[..];
注意:
- Range的范圍包含Start,不包含End。
- 所以索引為0的元素包含,索引為10或者
^0的元素不包含(盡管也不存在)。
更多例子
int[] arr = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] arr01 = arr[..]; //完整的復制,數組
int[] allButFirst = arr[1..]; //不包含第一個元素的數組
int[] empty = arr[^0..]; //空數組
int[] onlyLastItem = arr[^1..]; //只包含最后一個元素的數組
int[] last4Items = arr[^4..]; //只包含最后四個元素的數組
int lastItem = arr[^1]; //最后一個元素
單獨使用Range或Index
int[] arr = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Index middle = 4;
Index threeFromEnd = ^3;
Range range = middle..threeFromEnd;
int[] mySlice = arr[range]; //5, 6, 7
參考
- C# 8 - Range 和 Index(范圍和索引):https://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA==&mid=2654076610&idx=1&sn=8e04e2da923f44d04c642a0e0aabd7aa,好文,強烈推薦!!
