特定条目的LINQ索引

8qgya5xd  于 2023-11-14  发布在  其他
关注(0)|答案(5)|浏览(158)

我有一个MVC 3 C#.Net Web应用程序。我有下面的字符串数组。

public static string[] HeaderNamesWbs = new[]
                                       {
                                          WBS_NUMBER,
                                          BOE_TITLE,
                                          SOW_DESCRIPTION,
                                          HARRIS_WIN_THEME,
                                          COST_BOGEY
                                       };

字符串
我想在另一个循环中找到给定条目的索引。我以为列表会有一个IndexOf。我找不到它。有什么想法吗?

rta7y2nd

rta7y2nd1#

你可以使用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;


(The+1和-1是这样的,它将返回-1表示“missing”,而不是0。

7tofc5zh

7tofc5zh2#

我在这里的线程晚了。但我想分享我的解决方案。乔恩的是可怕的,但我更喜欢简单的所有东西。
你可以扩展LINQ本身来得到你想要的。这相当简单。这将允许你使用这样的语法:

// Gets the index of the customer with the Id of 16.
var index = Customers.IndexOf(cust => cust.Id == 16);

字符串
这可能不是LINQ默认的一部分,因为它需要枚举。它不仅仅是另一个延迟选择器/ predicate 。
另外,请注意,这只返回第一个索引。如果你想要索引(复数),你应该在方法内部返回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;
  }

h79rfbju

h79rfbju3#

如果要使用函数而不是指定项值来搜索List,则可以使用List.FindIndex( predicate 匹配)。
参见https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.findindex?view=netframework-4.8

5q4ezhmt

5q4ezhmt4#

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)

eblbsuwk

eblbsuwk5#

用于获取集合中任何项的偏移量(也称为从零开始的索引)的广义扩展方法。

/* by a value */
items.OffsetOf(item);
items.OffsetsOf(item);

/* by conditions */
items.OffsetOf(item => item.Id is "6174");
items.OffsetsOf(item => item.Id.StartsWith("abc"));

/* by conditions dependent from an item offset too */
items.OffsetOf((item, offset) => item.Id is "1729" && offset % 2 is 0);
items.OffsetsOf((item, offset) => item.Id.StartsWith("0") && offset % 2 is 1);

字符串
sharplab.io有一个Playground。
执行

public static class LinqExtensions
{
        public static int OffsetOf<T>(this IEnumerable<T> collection, Func<T, int, bool> match)
        {
            var offset = 0;
            foreach (var item in collection)
            {
                if (match(item, offset))
                    return offset;

                offset++;
            }

            return -1;
        }

        public static int OffsetOf<T>(this IEnumerable<T> collection, Func<T, bool> match) =>
            collection.OffsetOf((item, offset) => match(item));

        public static int OffsetOf<T>(this IEnumerable<T> collection, T value) =>
            collection.OffsetOf((item, offset) => item.Is(value));

        public static IEnumerable<int> OffsetsOf<T>(this IEnumerable<T> collection, Func<T, int, bool> match)
        {
            var offset = 0;
            foreach (var item in collection)
            {
                if (match(item, offset))
                    yield return offset;

                offset++;
            }
        }

        public static IEnumerable<int> OffsetsOf<T>(this IEnumerable<T> collection, Func<T, bool> match) =>
            collection.OffsetsOf((item, offset) => match(item));

        public static IEnumerable<int> OffsetsOf<T>(this IEnumerable<T> collection, T value) =>
            collection.OffsetsOf((item, offset) => item.Is(value));
    
        public static bool Equals<T>(T a, T b) => EqualityComparer<T>.Default.Equals(a, b);
        public static bool Is<T>(this T o, T x) => Equals(o, x); /* Equals<T>(o, x); */
}

相关问题