• C#&&数组


    数组是最常用的数据结构,几乎在所有的编程语言中都会出现。在C#里用数组的话需要建立一个System.Array类型的对象,它是所有数组的抽象基类。
    Array类提供了一组排序和查找的方法
    另一个可以建立数组的替代品是ArrayList,ArrayList是可以按需要动态增长的数组。
    在不能确定一个数组的大小的情况下,或在程序的生命周期内数组的大下需要改变时,ArrayList是个好的选择。
    还有包括拷贝,克隆的内容,比较是否相等以及用Array和ArrayList的静态方法。

    声明和初使化数组
    数组声明时用下面的格式:

    type[] array_name;
    type就是数据类型,比如
    string[] names;

    第二行需要实例化这个数组(因为是System.Array类型)并指定数组的大小。代码如下:
    names = new string[10];
    这样就为10个字符串分配了内存。

    也可以两句合在一起写:

    string[] names = new string[10];
    有时候你想把声明,实例化,指定数据三个步骤同时进行,那就这样子:
    int[] numbers = new int[] {1,2,3,4,5};
    这一串数字,叫做初使化列表,用花括号括起来,每个元素用逗号隔开。
    当用这种方式声明数组时,不用指定数组大小,编译器会自动根据初使化列表的个数来指定。

    设定和存取数组元素
    数组元素的存储既可以直接存储,也可以调用SetValue方法,直接存储方法需要用索引指定数组内的位置,向下面这样:

    Names[2] = "Raymond";
    Sales[19] = 23123;
    SetValue方法提供了一个更面向对象的做法去设置数组元素的值,此方法有两个参数,一个是索引数,另一个是值。
    names.SetValue[2, "Raymond"];
    sales.SetValue[19, 23123];
    数组元素的取出既可以直接取得,也可以调用GetValue方法,GetValue用一个简单的参数:索引数

    myName = names[2];
    monthSales = sales.GetValue[19];

    通过循环去取得数组内的每个元素是很常见的。程序员写循环时会经常犯一个错误:就是写死了循环的上限或调用取得上限的方法。
    错误主要是因为数组的上限是动态的
    for (int i = 0; i <= sales.GetUpperBound(0); i++)
    totalSales = totalSales + sales[i];
    检索数组元数据的方法和属性:
    Length:返回数组元素的所有个数。
    GetLength:返回数组元素一维内的个数。
    Rank:返回维数
    GetType:返回当前数组实例的类型

    Length方法在统计多维数组内元素的个数时很有用。要不然就用GetUpperBound方法+1取这个值
    因为Length方法返回的是数组内所有元素的个数,GetLength方法返回的是一维内数组的个数。
    Rank属性可以在运行时改变数组的大小而不用担心丢失数据,这个在章节后面详细讨论。
    GetType方法是当你确定不了数组类型时用来判定数据类型的方法,比如数组是入参。
    下面的代码,会创建一个Type类型的变量,允许我们调用一个类方法:IsArray()来判定这个对象是否是数组,
    如果是数组的话,那么就返回数组的数据类型
    int[] numbers;
    numbers = new int[] {0,1,2,3,4};
    Type arrayType = numbers.GetType();
    if (arrayType.IsArray)
    Console.WriteLine("The array type is: {0}", arrayType);
    else
    Console.WriteLine("Not an array");
    Console.Read();

    GetType方法不仅返回数组的类型,也告诉我们数组其实是一个对象,下面是输出的代码:
    The array type is: System.Int32[]
    方括号说明这个对象是个数组,也注意一下当显示数组类型时我们使用的格式。
    知道了这个,我们不能转换把这个类型转换成string去连接剩下的字符串

    多维数组
    目前我们的讨论都限于一维数组,C#里,可以用最多32维的数组,虽然3维以上的数组就不常用了(还混乱的很)。
    多维数组是用指定了每维上限的数组声明的,2维的声明:
    int[,] grades = new int[4,5];
    声明一个4行5列的数组,2维数组一般用来模拟矩阵。
    你也可以声明一个不指定每一维的上限的多维数组,用逗号分开就行了。
    举个例子:
    double[,] Sales;
    声明一个2维数组,
    double[,,] sales;
    声明一个3维数组,当你声明数组不指定某维的上限时,用的时候要指定

    多维数组也可以用初使化列表,看下面的代码:
    Int[,] grades = new int[,] {{1, 82, 74, 89, 100},
    {2, 93, 96, 85, 86},
    {3, 83, 72, 95, 89},
    {4, 91, 98, 79, 88}}
    首先,注意数组的上限是没有指定的,当用初使化列表来初使化一个数组时,
    不能指定该数组的上限。编译器会通过初使化列表计算每一维的上限。
    初使化列表本身是一对花括号,每一行,每一个元素都用逗号分开。

    取得多数组的元素和一维是差不多的,传统技术是这样的:

    grade = Grades[2,2];
    Grades[2,2] = 99
    或者也可以用GetValue方法
    grade = Grades.GetValue[0,2];

    但不能用SetValue方法来设置多维数组的数据,因为这个方法只有两个参数。

    在多维数组里计算所有元素是很常见的操作,虽然常常时是基于某一行或某一列的数据。
    用Grades这个数组,如果数组的每一行是一条学生记录,我们可以计算年级里每个学生的平均分:

    (代码如下)

    int[,] grades = new int[,] {{1, 82, 74, 89, 100},
                  {2, 93, 96, 85, 86},
                  {3, 83, 72, 95, 89},
                  {4, 91, 98, 79, 88}};
    int last_grade = grades.GetUpperBound(1);
    double average = 0.0;
    int total;
    int last_student = grades.GetUpperBound(0);
    for(int row = 0; row <= last_student; row++) {
        total = 0;
    for (int col = 0; col <= last_grade; col++)
          total += grades[row, col];
    average = total / last_grade;
    Console.WriteLine("Average: " + average);
      }
    }

    参数数组
    很多方法的定义需要提供好几个参数,但是有时候你想写一个参数个数可选的方法。
    你可以声明一个参数数组。参数数组是用关键字ParamArray定义参数列表的。
    下面这个方法允许任意个数的参数,返回值是参数的个数。static int sumNums(params int[] nums) {

    int sum = 0;
    for(int i = 0; i <= nums.GetUpperBound(0); i++)
    sum += nums[i];
    return sum;
    }

    这个方法可以被以下代码调用:

    total = sumNums(1, 2, 3);
    total = sumNums(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    当你用参数数组定义一个方法时,参数数组必须放在此方法所有参数的最后,
    这样编译器可以正确处理参数,否则,编译器不知道参数个数什么时候结束。

    不规则数组
    当你创建一个多维数组时,你一直创建的是每一行的元素个数相同的结构。打个比方,你看下面的代码:

    int sales[,] = new int[12,30];//销售员每个月每天的情况
    假设每行(每月)有同样的元素个数(天数),而实际上有的月31天,有的30天,有的29.
    这样数据就有空位置,在这个数组里问题倒不大,但是一旦数据量大了以后就很浪费了

    解决问题的方法是使用一个不规则数组来代替二维数组。
    不规则数组是一个数组的每一行也是数组的数组。不规则数组的每一维是一维数组,叫它“不规则”是因为每一行的个数不同。
    不规则数组的样子可能不是一个矩形,但是有不规则的边。
    不规则数组用数组名后的两对括号声明。第一对括号指定行数,第二对是留空的。
    int[][] jagged = new int[12][];

    这句代码看上去有点怪,但是分开来理解就明白了。这个不规则数组有12个元素。
    每个元素也是一个数组。初使化列表其实就是为了初使化每一行数据,说明每一行元素是有12个元素的数据,每个元素都初使成默认值。
    一旦不规则数组声明,每一行的元素就可以指定指了,下面的代码就是设置值的:
    jagged[0][0] = 23;
    jagged[0][1] = 13;
    . . .
    jagged[7][5] = 45;
    第一对括号指明行号,第二对括号指明这一行的某一个元素。
    第一句取第一行的第一个元素,第二句取第一行的第二个元素。
    第三句取第6行的第8个元素。

    一个用不规则数组的例子,下面的程序创建一个叫做sales的数组,循环用来计算这两个月每周的平均销售情况。

    using System;
    class class1 {
    static void Main[] {
    int[] Jan = new int[31];
    int[] Feb = new int[29];
    int[][] sales = new int{Jan, Feb};
    int month, day, total;
    double average = 0.0;
    sales[0][0] = 41;
    sales[0][1] = 30;
    sales[0][0] = 41;
    sales[0][1] = 30;
    sales[0][2] = 23;
    sales[0][3] = 34;
    sales[0][4] = 28;
    sales[0][5] = 35;
    sales[0][6] = 45;
    sales[1][0] = 35;
    sales[1][1] = 37;
    sales[1][2] = 32;
    sales[1][3] = 26;
    sales[1][4] = 45;
    sales[1][5] = 38;
    sales[1][6] = 42;
    for(month = 0; month <= 1; month++) {
    total = 0;
    for(day = 0; day <= 6; day++)
    total += sales[month][day];
    average = total / 7;
    Console.WriteLine("Average sales for month: " +
    month + ": " + average);
    }
    }
    }

    ArrayList类
    在不知道数组大小的情况或运行时数组大小要改变的情况下,静态数组就不是那么有用了。
    一个解决方是用一个空间不够用时可以自增长的数组类型,这个数组就是ArrayList,它也是System.Collections里的一部分。
    ArrayList类的对象有一个Capacity属性用来存储数组大小,初使值是16,当数组的元素接近16个时,Capacity会加16,
    当然同时数组空间也变大了。需要用ArrayList的情况是这样的:数组可能会变大或变小时,它比在标准数组里用ReDim更高效。
    这个第一章也说过,ArrayList存储的是对象类型,如果需要强类型数组,你应该用标准数组或其他数据结构。 

    以下是些常用的方法或属性:
     Add(): 向ArrayList添加一个元素.
     AddRange(): 向ArrayList添加一组元素.
     Capacity: 存储ArrayList可以容纳元素的个数
     Clear(): 从ArrayList中移除一个元素.
     Contains(): 判断是否有指定的元素存在于ArrayList.
     CopyTo(): 复制ArrayList或是ArrayList的一部分到一个Array类.
     Count: 返回ArrayList内的元素个数.
     GetEnumerator(): 返回一个ArrayList的迭代器.
     GetRange(): 返回ArrayList的一个子集.
     IndexOf(): 返回第一个发现的指定元素的索引.
     Insert(): 向ArrayList的指定位置插入一个元素.
     InsertRange(): 向ArrayList的指定位置插入一组元素
     Item(): 设置或取得某个指定位置的值.
     Remove(): 移除第一个发现的指定元素.
     RemoveAt(): 移除指定位置的元素.
     Reverse(): 逆序.
     Sort(): 按字母排序.
     ToArray(): 复制所有元素到一个Array类.
     TrimToSize(): 将Capacity值设置成与数组元素个数相等的值.

    使用ArrayList类
    ArrayList不像标准的数组。一般来说,添加元素用Add(),除非在特定位置添加,那就用Insert()。
    这里,我们测试一下怎么使用ArrayList的其他方法。
    首先声明一个对象ArrayList grades = new ArrayList();
    注意这里用了构造函数,如果ArrayList没有用构造函数,这个ArrayList对象就不能使用。
    用Add方法添加元素,这个方法只有一个参数,就是要添加到ArrayList的对象。
    Add方法有返回值,返回的插入的位置,只是很少用而已。下面是例子:
    grades.Add(100);
    grades.Add(84);
    int position;
    position = grades.Add(77);
    Console.WriteLine("The grade 77 was added at position:
    " + position);

    ArrayList对象可以用Foreach来遍历,ArrayList有一个内建的枚举器
    int total = 0;
    double average = 0.0;
    foreach (Object grade in grades)
    total += (int)grade;
    average = total / grades.Count;
    Console.WriteLine("The average grade is: " + average);

    如果你要添加元素到特定位置,用Insert方法,有两个参数,位置和值
    grades.Insert(1, 99);
    grades.Insert(3, 80);

    查看ArrayList当前的容量可以用Capacity属性,看数组个数可以用Count属性
    Console.WriteLine("The current capacity of grades is:
    " + grades.Capacity);
    Console.WriteLine("The number of grades in grades is:
    " + grades.Count);

    这里有些其他的方法移除元素,如果你知道要移除的元素,但不知道位置,用Remove方法,只有一个参数,就是这个你要移除的对象。
    如果这个对象存在于ArrayList中,会被移除,否则,什么都不做。就像是以下的代码。
    if (grades.Contains(54))
    grades.Remove(54)
    else
    Console.Write("Object not in ArrayList.");

    如果知道要移除的对象的位置,用RemoveAt方法,这个方法有一个参数:对象的索引。
    如果传入无效的索引则会异常。
    grades.RemoveAt(2);

    取得一个对象的索引用IndexOf方法,有一个参数,就是这个对象。返回这个对象的索引。如果不存在,返回-1
    int pos;
    pos = grades.IndexOf(70);
    grades.RemoveAt(pos);

    如果要添加对象集合的话,这组对象必须派生自ICollection,意思是说,这组对象可以存在于数组,Collection或者ArrayList里。
    这里有两个不同的方法去添加一组对象到ArrayList。AddRange和InsertRange,AddRange添加元素到末尾,InsertRange方法添加到指定位置。

    (代码如下)

    结果如下

    前面两个名字在ArrayList的开头是因为指定的索引是0.最后的那些名字在末尾是因为用的AaddRange。
    还有两个常用的方法是ToArray和GetRange方法。GetRange方法返回ArrayList里的一组对象做为新的ArrayList。
    ToArray方法复制所有元素到一个array元素

    GetRange方法有两个参数:开始的索引和要取得的元素个数。
    GetRange方法没有破坏性,只是取复本而已。下面是例子代码

    ArrayList someNames = new ArrayList();
    someNames = names.GetRange(2,4);
    Console.WriteLine("someNames sub-ArrayList: ");
    foreach (Object name in someNames)
    Console.WriteLine(name);

    总结:

    数组是最常用的数据结构。几乎所有的编程语言都内置了数组类型。
    很多应用程序里,数组是最简单最有效的数据结构,数组是很有用的。
    .net有一个新的数组类型叫做ArrayList,基本上和数组差不多,但更强的是它可以重新设置容量。
    ArrayList还有一些很有用的方法,比如插入,删除,以及查找。
    因为C#不允许程序员像VB.net那样动态变更数组的大小,ArrayList在不知道数组大小的情况下是很有用的数据结构。

  • 相关阅读:
    SharePoint Framework (SPFx) 开发入门教程
    SharePoint 2013 Designer 入门教程
    SharePoint 2013 开发教程
    SharePoint 2013 入门教程
    SharePoint Online 部署SPFx Web部件
    SharePoint Online SPFx Web部件绑定数据
    SharePoint Online 创建SPFx客户端Web部件
    SharePoint Online 配置框架(SPFx)开发环境
    SharePoint Online 创建应用程序目录
    SharePoint Online 启用 IRM
  • 原文地址:https://www.cnblogs.com/tjuxiepeng/p/4461338.html
Copyright © 2020-2023  润新知