LINQ indexOf 特定条目
Posted
技术标签:
【中文标题】LINQ indexOf 特定条目【英文标题】:LINQ indexOf a particular entry 【发布时间】:2012-03-07 04:41:10 【问题描述】:我有一个 MVC3 C#.Net 网络应用程序。我有下面的字符串数组。
public static string[] HeaderNamesWbs = new[]
WBS_NUMBER,
BOE_TITLE,
SOW_DESCRIPTION,
HARRIS_WIN_THEME,
COST_BOGEY
;
我想在另一个循环中找到给定条目的索引。我认为该列表会有一个 IndexOf。我找不到它。有什么想法吗?
【问题讨论】:
LINQ 对没有索引运算符的集合进行操作。没有IndexOf
@cadrell0:您可以轻松构建一个 - 请参阅我的答案。有各种提供索引的 LINQ 运算符。
【参考方案1】:
你可以使用Array.IndexOf
:
int index = Array.IndexOf(HeaderNamesWbs, someValue);
或者只是将HeaderNamesWbs
声明为IList<string>
- 如果您愿意,它仍然可以是一个数组:
public static IList<string> HeaderNamesWbs = new[] ... ;
请注意,我不鼓励您将数组公开为 public static
,甚至是 public static readonly
。你应该考虑ReadOnlyCollection
:
public static readonly ReadOnlyCollection<string> HeaderNamesWbs =
new List<string> ... .AsReadOnly();
如果你想为IEnumerable<T>
使用这个,你可以使用:
var indexOf = collection.Select((value, index) => new value, index )
.Where(pair => pair.value == targetValue)
.Select(pair => pair.index + 1)
.FirstOrDefault() - 1;
(+1 和 -1 是为了让“丢失”返回 -1 而不是 0。)
【讨论】:
@Jon...谢谢!好东西。我喜欢 ReadOnlyCollection 的想法...欣赏它 @jon-skeet 设置默认的-1
不是更有意义吗? collection.Select((value, index) => new value, index ).Where(pair => pair.value == targetValue).Select(pair => pair.index).FirstOrDefault(-1);
@lund.mikkel:FirstOrDefault
没有过载,它采用默认值来提供(例如,与 DefaultIfEmpty
不同)。
indexOf = collection.SelectMany((value, index) => value == targetValue ? new [] index : Enumerable.Empty<int>()).DefaultIfEmpty(-1).First()
@ImrePühvel:虽然我同意这是否是一个全新的 API,但我认为让 this 索引操作的行为方式与其他操作完全相同是合理的框架中的IndexOf
方法。【参考方案2】:
我来晚了。但我想分享我的解决方案。 Jon's 很棒,但我更喜欢简单的 lambdas。
您可以扩展 LINQ 本身以获得您想要的。这很简单。这将允许您使用如下语法:
// Gets the index of the customer with the Id of 16.
var index = Customers.IndexOf(cust => cust.Id == 16);
默认情况下,这可能不是 LINQ 的一部分,因为它需要枚举。这不仅仅是另一个延迟选择器/谓词。
另外,请注意这仅返回第一个索引。如果你想要索引(复数),你应该在方法中返回一个IEnumerable<int>
和yield return index
。当然不要返回-1。如果您不按主键进行过滤,这将很有用。
public static int IndexOf<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
var index = 0;
foreach (var item in source)
if (predicate.Invoke(item))
return index;
index++;
return -1;
【讨论】:
【参考方案3】:如果你想用函数而不是指定项值来搜索 List,你可以使用 List.FindIndex(Predicate match)。
见https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.findindex?view=netframework-4.8
【讨论】:
【参考方案4】:对List
有IndexOf(),只需将其声明为ILIst<string>
而不是string[]
public static IList<string> HeaderNamesWbs = new List<string>
WBS_NUMBER,
BOE_TITLE,
SOW_DESCRIPTION,
HARRIS_WIN_THEME,
COST_BOGEY
;
int index = HeaderNamesWbs.IndexOf(WBS_NUMBER);
MSDN:List(Of T).IndexOf Method (T)
【讨论】:
以上是关于LINQ indexOf 特定条目的主要内容,如果未能解决你的问题,请参考以下文章
IndexOf() LastIndexOf() Contains() StartsWith() EndsWith()方法比较