我有一个 MVC3 C#.Net Web 应用程序。我有下面的字符串数组。
public static string[] HeaderNamesWbs = new[]
{
WBS_NUMBER,
BOE_TITLE,
SOW_DESCRIPTION,
HARRIS_WIN_THEME,
COST_BOGEY
};
我想在另一个循环中找到给定条目的索引。我认为列表会有一个 IndexOf。我找不到它。有什么想法吗?
那么你可以使用
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 很棒,但我更喜欢简单的 lambda 表达式。
您可以扩展 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;
}
如果你想用函数来搜索List而不是指定一个item值,你可以使用List.FindIndex(Predicate match)。
右
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);
用于将任何项目的偏移量[又名从零开始的索引(ex)]获取到集合中的通用扩展方法。
/* 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 上有 游乐场。
实施
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); */
}