在数组中查找值的索引


113

可以使用linq以某种方式在数组中查找值的索引吗?

例如,此循环在数组中定位键索引。

for (int i = 0; i < words.Length; i++)
{
    if (words[i].IsKey)
    {
        keyIndex = i;
    }
}

实际上,只知道这个词也是可以的。
零零

Answers:


183
int keyIndex = Array.FindIndex(words, w => w.IsKey);

实际上,无论您创建了哪个自定义类,实际上都会为您提供整数索引而不是对象


1
为什么System.Linq默认情况下不将其转换为扩展方法?那就是其他所有这样的地方!
qJake

63

对于数组,您可以使用 Array.FindIndex<T>

int keyIndex = Array.FindIndex(words, w => w.IsKey);

对于列表,您可以使用List<T>.FindIndex

int keyIndex = words.FindIndex(w => w.IsKey);

您还可以编写适用于任何对象的通用扩展方法Enumerable<T>

///<summary>Finds the index of the first item matching an expression in an enumerable.</summary>
///<param name="items">The enumerable to search.</param>
///<param name="predicate">The expression to test the items against.</param>
///<returns>The index of the first matching item, or -1 if no items match.</returns>
public static int FindIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate) {
    if (items == null) throw new ArgumentNullException("items");
    if (predicate == null) throw new ArgumentNullException("predicate");

    int retVal = 0;
    foreach (var item in items) {
        if (predicate(item)) return retVal;
        retVal++;
    }
    return -1;
}

您也可以使用LINQ:

int keyIndex = words
    .Select((v, i) => new {Word = v, Index = i})
    .FirstOrDefault(x => x.Word.IsKey)?.Index ?? -1;

2
还有一个List(T).FindIndex方法
tdc

@Paolo从Lambda生成的列表怎么样?我得到谓词错误。
米希尔·帕特尔

10
int keyIndex = words.TakeWhile(w => !w.IsKey).Count();

3
+1但是,如果项目不存在怎么办?我们将得到0,但索引为-1
Arsen Mkrtchyan

@ArsenMkrtchyan如果该项目不存在,则会产生文字。长度
Jim Balter

@ArsenMkrtchyan您写了“我们将得到0”……这是错误的。您写了“但索引为-1”……这也是错误的。-1是失败的常见指示,但不是唯一可能的指示。不在0..words.Length-1之内的任何值都可以。
Jim Balter

1
@JimBalter,我的意思是,如果item不存在,表达式将返回0,这是怎么回事?我同意-1为通用指标,但很显然99%的案例-1是不存在项目时的期望值。当项目不存在时,至少0是错误的
Arsen Mkrtchyan

7

如果您想查找单词,可以使用

var word = words.Where(item => item.IsKey).First();

这将为您提供IsKey为true的第一项(如果可能不存在,则可能要使用 .FirstOrDefault()

要获取项目和索引,您可以使用

KeyValuePair<WordType, int> word = words.Select((item, index) => new KeyValuePair<WordType, int>(item, index)).Where(item => item.Key.IsKey).First();

linq疯了。我以为Java泛型太疯狂了。无论如何,感谢您的所有帮助。
零零

是否强制转换返回值是惯例,还是有办法定义单词的类型?
零零

好的,我想到了这个。DecodedMessageWord keyWord = words.Where(x => x.IsKey == true).First <DecodedMessageWord>();
零零

5
@initialZero会检查for的重载First,它需要一个谓词,您不需要Where
Yuriy Faktorovich 2012年

3

试试这个...

var key = words.Where(x => x.IsKey == true);

2
与Grizzly和masenkablast的答案相比,这似乎是一个很弱的解决方案。masenkablast回答了原始问题,而Grizzly提供了一个更好的解决方案,因为他的最终“ var”将是实际单词,而不是包含1个单词的IEnumerable <TSource>。
詹姆斯



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.