CSharp中列表List/数组Array相关的处理

遍历

在遍历的时候,我们尽量不要对List进行遍历,因为List的长度是可变的,如果遍历的时候发生改变,就会报错。

推荐在遍历前把List转为Array

1
2
3
4
OnlineUser[] onlineUserArr = ZCommonData.OnlineUserList.ToArray();
foreach (OnlineUser user in onlineUserArr)
{
}

转换

使用 LINQ 查询来实现将列表中的每个元素拼接一个固定字符串,并生成一个新的列表。

以下是一个示例:

1
2
3
4
5
6
7
8
List<int> numbers = new List<int>{1,2,3};
List<string> incrementedNumbers = numbers.Select(num => "num_" + num).ToList();

// 输出增加后的列表
foreach (string str in incrementedNumbers)
{
Console.Write(str);
}

字符串转字符串数组

1
string[] _selectArr = "ABCDEFGHIJK".Select(c => c.ToString()).ToArray();

过滤

在 C# 中,你可以使用 LINQ(Language Integrated Query)来进行列表的筛选(Filter)操作。

通过 LINQ,你可以使用 Where 方法来筛选列表中的元素。

下面是一个简单的示例,演示如何使用 LINQ 的 Where 方法对 List 进行筛选操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// 使用 Where 方法筛选出大于5的元素
IEnumerable<int> filteredNumbers = numbers.Where(n => n > 5);

foreach (int number in filteredNumbers)
{
Console.WriteLine(number);
}
}
}

在上面的示例中,我们创建了一个包含数字的列表 numbers,然后使用 LINQ 的 Where 方法筛选出其中大于5的元素,并将结果存储在 filteredNumbers 中。最后,我们遍历输出了筛选后的结果。

通过使用 LINQ 的 Where 方法,你可以根据自定义的条件对列表进行灵活的筛选操作。

子列表(分页)

对于列表

在C#中,你可以使用List<T>类的GetRange方法来获取一个列表的子列表。

GetRange方法接受两个参数,第一个是子列表的起始索引,第二个是子列表的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;

class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// 获取从索引 2 开始的 3 个元素,也就是子列表 [3, 4, 5]
List<int> subList = numbers.GetRange(2, 3);

// 输出子列表的元素
foreach (int num in subList)
{
Console.Write(num + " ");
}

// 输出结果为 "3 4 5"
}
}

对于ObservableCollection

ObservableCollection<T>类并没有提供类似List<T>GetRange方法。

如果你想从一个ObservableCollection<T>中获取子集,你可以使用 LINQ 查询来实现。

以下是一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.ObjectModel;
using System.Linq;

class Program
{
static void Main()
{
ObservableCollection<int> numbers = new ObservableCollection<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// 获取从索引 2 开始的 3 个元素,也就是子集 [3, 4, 5]
ObservableCollection<int> subCollection = new ObservableCollection<int>(numbers.Skip(2).Take(3));

// 输出子集的元素
foreach (int num in subCollection)
{
Console.Write(num + " ");
}

// 输出结果为 "3 4 5"
}
}

在上述示例中,我们使用Skip方法跳过前两个元素,然后使用Take方法获取接下来的三个元素,从而创建了一个子集。

数组展平

二维数组变成一维数组

SelectMany方法可以用于将多个集合合并成一个集合。

SelectMany 方法在 LINQ 中用于将一个序列中的每个元素投影到一个序列中,然后将所有的序列合并为一个序列。这通常用于处理嵌套集合或者对集合中的每个元素执行一些操作并将结果合并到单个集合中。

下面是一个简单的示例,演示如何使用 SelectMany 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
static void Main()
{
List<List<int>> listOfLists = new List<List<int>>
{
new List<int> { 1, 2, 3 },
new List<int> { 4, 5, 6 },
new List<int> { 7, 8, 9 }
};

// 使用 SelectMany 方法将嵌套列表合并为单个列表
IEnumerable<int> flattenedList = listOfLists.SelectMany(list => list);

foreach (int number in flattenedList)
{
Console.WriteLine(number);
}
}
}

在上面的示例中,我们有一个包含多个整数列表的列表 listOfLists

我们使用 SelectMany 方法将这些嵌套的列表合并为单个列表 flattenedList,然后遍历输出了合并后的结果。

这是 SelectMany 方法的一个简单示例,你可以根据需要自定义投影操作以及合并逻辑。

数组聚合操作

数组聚合操作是指在数组中对元素进行计算或者合并的操作。

这些操作通常包括对数组中的元素进行求和、计算平均值、找到最大值或最小值等等。

在C#中,可以使用LINQ(Language Integrated Query)来执行各种数组聚合操作。

LINQ提供了一套丰富的操作符和方法,可以方便地对数组进行查询和转换。

以下是一些常见的数组聚合操作示例:

求和(Sum)

1
2
int[] numbers = { 1, 2, 3, 4, 5 };
int sum = numbers.Sum(); // 结果为 15

计算平均值(Average)

1
2
int[] numbers = { 1, 2, 3, 4, 5 };
double average = numbers.Average(); // 结果为 3

找到最大值(Max)

1
2
int[] numbers = { 1, 2, 3, 4, 5 };
int max = numbers.Max(); // 结果为 5

找到最小值(Min)

1
2
int[] numbers = { 1, 2, 3, 4, 5 };
int min = numbers.Min(); // 结果为 1

统计符合条件的元素个数(Count)

1
2
int[] numbers = { 1, 2, 3, 4, 5 };
int count = numbers.Count(n => n % 2 == 0); // 结果为 2,统计偶数的个数

检查是否存在符合条件的元素(Any)

1
2
int[] numbers = { 1, 2, 3, 4, 5 };
bool anyGreaterThanTen = numbers.Any(n => n > 10); // 结果为 False

数组转List

1
2
3
4
5
// 假设有一个整数数组
int[] array = { 1, 2, 3, 4, 5 };

// 使用ToList()方法将数组转换为List<int>
List<int> list = array.ToList();

List判断是否包含

1
2
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
numbers.Contains(3)

或者

使用Linq可以判断子属性

1
2
3
4
5
6
7
8
9
10
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
bool containsNumber = numbers.Any(x => x == 3);
if (containsNumber)
{
Console.WriteLine("列表包含数字3" );
}
else
{
Console.WriteLine("列表不包含数字3");
}

列表元素索引

你可以使用 LINQ 查询或者循环来在列表中查找符合条件的索引。

以下是两种方法的示例:

方法一:使用 LINQ 查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };

int target = 5;

// 使用 LINQ 查询找到符合条件的索引
int index = numbers.FindIndex(n => n == target);

if (index != -1)
{
Console.WriteLine("找到了,索引为:" + index);
}
else
{
Console.WriteLine("未找到");
}
}
}

在上述示例中,我们使用了 List<T>.FindIndex 方法和一个 lambda 表达式来查找符合条件的元素索引。

方法二:使用循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;

class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };

int target = 5;
int index = -1;

for (int i = 0; i < numbers.Count; i++)
{
if (numbers[i] == target)
{
index = i;
break;
}
}

if (index != -1)
{
Console.WriteLine("找到了,索引为:" + index);
}
else
{
Console.WriteLine("未找到");
}
}
}

在这个示例中,我们使用一个简单的 for 循环来遍历列表,检查每个元素是否符合条件。

无论使用哪种方法,都可以在列表中查找符合条件的索引。如果找到了符合条件的元素,将返回该元素的索引;如果未找到,则返回一个指示未找到的值(通常是 -1)。

数组元素索引

C#数组对象自身没有获取索引的方法,要用Array.IndexOf方法。

要获取 C# 数组中某个元素的索引,你可以使用Array.IndexOf方法或者自己编写一个循环进行搜索。

使用Array.IndexOf方法的语法如下所示:

1
int index = Array.IndexOf(array, value);

其中,array是要搜索的数组,value是要查找的元素。如果找到了该元素,index将返回其在数组中的索引;如果未找到,index将返回-1。

以下是一个示例:

1
2
3
int[] numbers = { 2, 4, 6, 8, 10 };
int index = Array.IndexOf(numbers, 6);
Console.WriteLine("元素6的索引为:" + index);

输出结果为:

1
元素6的索引为:2

列表排序

简单排序

在 C# 中,List<T>Sort 方法会改变原始列表的顺序,而不会创建新的列表。

这意味着调用 Sort 方法后,原始 List<T> 的元素顺序会被修改,而不会返回新的列表副本。

这种行为称为“原地排序”(in-place sorting),即直接在原始数据结构上进行排序操作,而不是创建一个新的已排序副本。

例如,如果有一个 List<int>

1
List<int> numbers = new List<int> { 3, 1, 4, 1, 5, 9, 2, 6, 5 };

调用 numbers.Sort() 后,numbers 列表的元素顺序将被排序:

1
numbers.Sort(); // 现在 numbers = { 1, 1, 2, 3, 4, 5, 5, 6, 9 }

因此,如果需要保留原始列表的顺序,并且获取排序后的新列表,可以使用 LINQ 的 OrderBy 方法:

1
List<int> sortedNumbers = numbers.OrderBy(x => x).ToList();

这将返回一个新的已排序列表 sortedNumbers,而不影响原始列表 numbers 的顺序。

总结:List<T>Sort 方法会直接改变原始列表的顺序,而不是返回新的已排序副本。

单字段排序

随机排序

1
List<ClassStudentModel> randomUserList = allUserList.OrderBy(x => Guid.NewGuid()).ToList();

正序

1
List<ClassStudentModel> randomUserList = allUserList.OrderBy(x => x.num).ToList();

倒序

1
List<ClassStudentModel> randomUserList = allUserList.OrderByDescending(x => x.num).ToList();

多次排序

随机排序后再按字段正序

1
List<ClassStudentModel> randomUserList = allUserList.OrderBy(x => Guid.NewGuid()).ToList().OrderBy(x => x.num).ToList();

随机排序后再按字段倒序

1
List<ClassStudentModel> randomUserList = allUserList.OrderBy(x => Guid.NewGuid()).ToList().OrderByDescending(x => x.num).ToList();

多字段同时排序

两个字段排序 先按Name正序再按num正序

1
List<ClassStudentModel> randomUserList = allUserList.OrderBy(x => x.Name).ThenBy(x => x.num).ToList();

两个字段排序 先按Name正序再按num倒序

1
List<ClassStudentModel> randomUserList = allUserList.OrderBy(x => x.Name).ThenByDescending(x => x.num).ToList();