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&lt;T&gt; 使用这个,你可以使用:

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) =&gt; new value, index ).Where(pair =&gt; pair.value == targetValue).Select(pair =&gt; pair.index).FirstOrDefault(-1); @lund.mikkel:FirstOrDefault 没有过载,它采用默认值来提供(例如,与 DefaultIfEmpty 不同)。 indexOf = collection.SelectMany((value, index) =&gt; value == targetValue ? new [] index : Enumerable.Empty&lt;int&gt;()).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&lt;int&gt;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&lt;string&gt; 而不是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 特定条目的主要内容,如果未能解决你的问题,请参考以下文章

Linq学习日记-模糊查询

IndexOf() LastIndexOf() Contains() StartsWith() EndsWith()方法比较

为啥 indexOf 找不到对象?

字符串数组中的 indexOf

为啥让 .indexOf() 返回为 -1,尽管元素存在于数组中? [关闭]

jquery判断字符串中是否包含特定字符的方法总结