C# ienumerable字符串列表中字符串的索引或位置
可能重复:C# ienumerable字符串列表中字符串的索引或位置,c#,.net,string,visual-studio-2010,.net-4.0,C#,.net,String,Visual Studio 2010,.net 4.0,可能重复: 我有下面这个函数,它接受ienumerable字符串列表 我循环遍历所有字符串,如果其值等于“TestName”(不区分大小写),则返回其位置 int GetMyTestColumnPosition(IEnumerable<string> TitleNames) { foreach (var test in TitleNames) { if (string.Compare(test, "testna
我有下面这个函数,它接受ienumerable字符串列表 我循环遍历所有字符串,如果其值等于“
TestName
”(不区分大小写),则返回其位置
int GetMyTestColumnPosition(IEnumerable<string> TitleNames)
{
foreach (var test in TitleNames)
{
if (string.Compare(test, "testname", stringComparison.CurrentCultureIgnoreCase) == 0)
{
// return TitleNames.IndexOf(test); does not work!
}
}
}
int GetMyTestColumnPosition(IEnumerable TitleNames)
{
foreach(滴定仪中的var测试)
{
if(string.Compare(test,“testname”,stringComparison.CurrentCultureIgnoreCase)==0)
{
//返回TitleNames.IndexOf(test);不起作用!
}
}
}
编辑:我将参数更改为“IList
”,这样就行了!但是,
IEnumerable
是一个简单的枚举器,不支持索引。来自MSDN关于
表示一个非泛型的对象集合,可以
通过索引单独访问
IEnumerable
是一个简单的枚举器,不支持索引。因为IEnumerable用于枚举,所以它们没有IndexOf方法也就不足为奇了。如果需要,可以创建扩展方法
但是,既然您已经在枚举,那么再次计算索引又有什么意义呢?这样做:
int index = 0;
foreach(var test in TitleNames)
{
if(...) return index;
index++;
}
仔细想想,这就是您想要的扩展方法:
public static int IndexOf(this IEnumerable<T> list, T item)
{
int index = 0;
foreach(var l in list)
{
if(l.Equals(item))
return index;
index++;
}
return -1;
}
public static int IndexOf(此IEnumerable列表,T项)
{
int指数=0;
foreach(列表中的变量l)
{
如果(l.等于(项目))
收益指数;
索引++;
}
返回-1;
}
请记住添加空值检查,并可能提供一个可选的比较器。好吧,因为IEnumerables用于枚举,所以它们没有IndexOf方法也就不足为奇了。如果需要,可以创建扩展方法 但是,既然您已经在枚举,那么再次计算索引又有什么意义呢?这样做:
int index = 0;
foreach(var test in TitleNames)
{
if(...) return index;
index++;
}
仔细想想,这就是您想要的扩展方法:
public static int IndexOf(this IEnumerable<T> list, T item)
{
int index = 0;
foreach(var l in list)
{
if(l.Equals(item))
return index;
index++;
}
return -1;
}
public static int IndexOf(此IEnumerable列表,T项)
{
int指数=0;
foreach(列表中的变量l)
{
如果(l.等于(项目))
收益指数;
索引++;
}
返回-1;
}
只需记住添加空值检查,并可能提供可选的比较器。您可以将重载中的索引传递到
选择或其中:
var found = TitleNames
.Select((str, index) => new { str, index })
.Where(x => x.str.Equals("testname", StringComparison.CurrentCultureIgnoreCase))
.FirstOrDefault();
if (found != null)
return found.index;
return -1;
您可以将重载中的索引传递到选择
或其中
:
var found = TitleNames
.Select((str, index) => new { str, index })
.Where(x => x.str.Equals("testname", StringComparison.CurrentCultureIgnoreCase))
.FirstOrDefault();
if (found != null)
return found.index;
return -1;
TitleNames
是IEnumerable
,因此它不支持索引
您不能依赖枚举:
int i = 0;
foreach(var test in TitleNames)
{
i++;
}
计算索引
您可以构建自己的类,该类继承自IEnumerable
,并在枚举时以随机顺序返回对象
如果大多数具体的.Net类型通常都是索引友好的,那么这只是实现细节
所以,为了回答您的问题:您无法从IEnumerable
获取对象的索引。如果需要索引支持,请使用IList。TitleNames
是IEnumerable
,因此它不支持索引
您不能依赖枚举:
int i = 0;
foreach(var test in TitleNames)
{
i++;
}
计算索引
您可以构建自己的类,该类继承自IEnumerable
,并在枚举时以随机顺序返回对象
如果大多数具体的.Net类型通常都是索引友好的,那么这只是实现细节
所以,为了回答您的问题:您无法从IEnumerable
获取对象的索引。如果您想要索引支持,请使用IList
。请参阅Jon Skeet的SmartEnumerable类,该类非常适用于此:如果您使用IList titleNames
,您甚至不需要编写自己的方法,因为titleNames.IndexOf(“testname”)
在这种情况下给出了您的结果。如果要使用IEnumerable
,LINQ将非常有用。下面是完整的方法:int GetMyTestColumnPosition(IEnumerable titleNames){return titleNames.Select(Tuple.Create).Where(t=>string.Equals(t.Item1,“testname”,StringComparison.CurrentCultureIgnoreCase)).Select(t=>t.Item2.DefaultIfEmpty(-1).First();
请参阅Jon Skeet的SmartEnumerable类,这一点非常有用:如果您使用IList titleNames
您甚至不需要编写自己的方法,因为titleNames.IndexOf(“testname”)
在这种情况下会给出您的结果。如果要使用IEnumerable
,LINQ将非常有用。下面是完整的方法:int-GetMyTestColumnPosition(IEnumerable titleNames){return titleNames.Select(Tuple.Create).Where(t=>string.Equals(t.Item1,“testname”,StringComparison.CurrentCultureIgnoreCase)).Select(t=>t.Item2.DefaultIfEmpty(-1).First();
这将起作用,但在LINQ不是您的朋友的情况下是很明显的。一个普通的循环(如OP had,但带有跟踪索引)对读者来说会更清晰,而且可能也会更快。&我会使用FirstOrDefault
和空检查,而不是Any
和First
并迭代两次。感谢linq版本@Tim@Tim如果第一个匹配项是列表中的最后一项,Any
将遍历整个列表以找到匹配项,然后First
将再次遍历该列表以找到第一项。@Rawling:Touché!;)(编辑)这会起作用,但很明显LINQ不是你的朋友。一个普通的循环(如OP had,但带有跟踪索引)对读者来说会更清晰,也可能更快