在数组中查找元素
数组操作基本上都是由Array类来负责,因而该类也提供了一系列方法来用于在数组中进行查找。这些方法按照查找结果划分,大体可以分为两类,下面将分别介绍。
1. 查找元素的索引
此种查找方式将返回被查找到的元素的索引,如果未找到,就返回-1。有两种方法可用:第一组是按照单个元素值来查找;第二组方法则比较灵活,可以通过System.Predicate委托来自定义查找过程。如下:
第一组:
- IndexOf() —— 查找指定元素的索引,只要遇到符合条件的元素就停止查找。如果数组存在多个相同的元素,那么方法只返回第一个满足条件的元素的索引。例如,一个数组中有2、2、3、5四个元素,查找元素2,只返回第一个2的索引,第二个2将被忽略。
- LastIndexOf() —— 与IndexOf()方法相似,但LastIndexOf方法返回匹配的最后一个元素的索引。例如一个数组中包含a、b、c、c、d五个元素,在查找元素c时,只返回第二个c的索引。
第二组:
- FindIndex —— 与IndexOf方法相似,只是可以使用Predicate委托来自定义查找方式,方法会把每个元素传给该委托,如果元素符合查找条件,则返回true,否则返回false。同样,FindIndex方法一旦找到第一个符合条件的元素就停止查找。
- FindLastIndex —— 通过Predicate委托来自定义查找,返回匹配查找条件的最后一个元素的索引。
在上面方法的参数中涉及Predicate委托,它的定义原型如下:
public delegate bool Predicate<in T>(T obj);
T是类型参数,该委托接受以T类型作为参数,并返回bool类型的方法,obj是数组中待查找的元素,如果obj符合查找条件,就返回true,否则就返回false。
下面用一个示例演示如何使用上面所列出的方法来查找元素的索引。
首先,声明一个数组变量,用于做测试。
//用于测试的数组
string[] testArr = new string[]
{
"ask",
"check",
"ask",
"food",
"ink"
};
数组中包含五个string类型的元素。随后分别用IndexOf、LastIndexOf、FindIndex和FindLastIndex四个方法来对测试数组进行查找,并在屏幕上输出查找到的索引。
//check是数组的第二个元素,索引为1
int index1 = Array.IndexOf(testArr,"check");
System.Console.WriteLine($"check元素的索引:{index1}");
//数组中存在两个ask,索引分别为0和2
//LastIndexOf方法只返回最后一个ask的索引2
int index2 = Array.LastIndexOf(testArr,"ask");
System.Console.WriteLine($"测试数组中有两个ask元素,LastIndexOf方法返回的索引:{index2}");
//通过自定义方式,查找以k结尾的元素
//第一个元素ask就是k结尾,已满足条件,不再往下查找
//因此返回第一个ask的索引0
int index3 = Array.FindIndex(testArr,new Predicate<string>(FindProc));
System.Console.WriteLine($"FindIndex方法查找以k结尾的元素的索引:{index3}");
//自定义方式查找以k结尾的元素
//测试数组中索引0、1、2、3、4四处的元素都以k结尾
//但FindLastIndex只返回最后一个匹配项ink的索引4
int index4 = Array.FindLastIndex(testArr,FindProc);
System.Console.WriteLine($"FindLastIndex方法查找以k结尾的元素的索引:{index4}");
"check"是数组的第二个元素,索引为1,故index1的值为1;测试数组中有两个"ask"元素,分别是第一个和第三个,LastIndexOf方法返回匹配的最后一项的索引,虽然索引0和2处都找到"ask"元素,但是由于索引2处是最后一处,故index2变量的值为2;在测试数组中有四个元素是k结尾的,但FindIndex只返回第一个匹配项的索引,因为第一个元素"ask"就是以k结尾的,符合条件,所以index3的值为0;FindLastIndex方法返回最后一个以k结尾的元素"ink"的索引,所以index4变量的值为4。
下面的代码是自定义查找方式的FindProc方法的处理过程。
private static bool FindProc(string obj)
{
if (obj.EndsWith("k"))
{
return true;
}
return false;
}
运行结果如下:
check元素的索引:1
测试数组中有两个ask元素,LastIndexOf方法返回的索引:2
FindIndex方法查找以k结尾的元素的索引:0
FindLastIndex方法查找以k结尾的元素的索引:4
2. 查找元素自身
这种查找方式的结果不是返回元素在数组中的索引,而是直接返回元素自身,也就是返回所找到的元素的值。Array类提供了三个方法用于查找元素,它们分别是:
- Find方法:查找符合条件的元素,如果找到,就不再往下查找;如果没有找到满足条件的元素,则返回类型的默认值。例如,如果要查找的目标类型是int,在找不到符合条件的元素时就返回int的默认值0。
- FindLast方法:查找满足条件的元素,并返回符合条件的最后一个元素,和FindLastIndex方法类似。例如,一个整形数组包含1、2、3、4四个元素,如果查找的条件是小于4的元素,那么符合条件的元素有1、2、3三个,FindLast方法将返回最后匹配的元素,即返回3。
- FindAll方法:按照指定的条件进行查找,返回所有符合条件的元素,以数组的形式返回。例如,一个int数组包含1、2、3、4四个元素,查找条件为小于3的元素,则FindAll方法将返回一个新的int数组,该数组包含符合条件的两个元素1和2。
示例如下:
定义一个int数组:
//声明数组变量
int[] arr = {3,6,35,10,9,13};
分别使用Find、FindLast和FindAll三个方法在数组中查找小于10的元素,并输出查找结果。
//Find方法只返回匹配的第一个元素
//数组中第一个小于10的元素是3,故返回3
int result = Array.Find(arr,new Predicate<int>(FindCallback));
System.Console.WriteLine($"Find方法查找小于10的元素:{result}");
//FindLast方法返回匹配元素的最后一项
//数组中最后一个小于10的元素是9,故返回9
int result2 = Array.FindLast(arr,FindCallback);
System.Console.WriteLine($"FindLast方法查找小10的元素:{result2}");
//FindAll方法返回所有匹配的元素
//数组中3,6,9都小于10
//因此,返回一个由3、6、9三个元素组成的数组
int[] result3 = Array.FindAll(arr,FindCallback);
System.Console.WriteLine("FindAll方法查找所有小于10的元素:");
foreach(int x in result3)
{
Console.Write(x+" ");
}
数组中小于10的有三个元素:3、6、9。Find方法只返回第一个符合条件的元素,所以返回3;FindLast方法返回符合条件的最后一个元素,所以返回9;FindAll方法返回所有符合条件的元素,因此返回3、6、9。
FindCallback方法的定义如下,用于Predicate委托。如果元素小于10则返回true,否则返回false。
private static bool FindCallback(int val)
{
if(val < 10)
{
return true;
}
return false;
}
示例运行结果如下:
Find方法查找小于10的元素:3
FindLast方法查找小10的元素:9
FindAll方法查找所有小于10的元素:
3 6 9