如何在整数列表中找到满足某些条件的项目的索引?

20

我有一个包含整数{10, 11, 23, 34, 56, 43}的列表,我想找出所有大于23的项的索引。这些值可以是任何顺序,所以我不想对它们进行排序。

List<int> mylist = new List<int> { 10, 11, 23, 34, 56, 43 };

我对所有符合条件的项的索引感兴趣,而不仅仅是符合条件的第一项。所以这行代码对我来说不起作用。

int index = mylist.FindIndex( x => x > 23 );
4个回答

30
var indexes = mylist.Select((v, i) => new { v, i })
                    .Where(x => x.v > 23)
                    .Select(x => x.i);

获取第一个出现的索引,代码如下:_list.Select((v, i) => new {v, i}).Where(x => x.v.Priority > activity.Priority).Select(x => x.i).First(); - gregsdennis
2
@gregsdennis _list.Select((v, i) => new {v, i}).First(x => x.v.Priority > activity.Priority).i; _list是一个列表,Select方法会将每个元素映射为一个新的对象,包含原始元素和它的索引。然后使用First方法找到第一个满足条件(v.Priority > activity.Priority)的元素,并返回它的索引i。 - Edwin Stoteler
1
@EdwinStoteler,好的。 :) - gregsdennis
有人能解释一下 Select((v, i)... 是如何工作的吗?为什么 i 包含索引? - A.Pissicat
@A.Pissicat,很容易: https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/System.Core/System/Linq/Enumerable.cs#L47C37-L47C37 如果我没有弄错的话,这是第47行。 - Taras Kyryliuk

1
Linq并没有直接提供这样的功能,但您可以自己编写。可以像下面这样实现:
public static IEnumerable<int> FindIndices<T>(this IEnumerable<T> items, Func<T, bool> predicate) 
{
    int i = 0;

    foreach (var item in items) 
    {
        if (predicate(item)) 
        {
            yield return i;
        }

        i++;
    }
}

然后类似这样:

foreach (int index in mylist.FindIndices( x => x > 23 ))
    ...

这种方法比上述其他方法更高效。然而,这只对大型序列有显著意义!


该方法返回单个值。 - User1551892
谢谢,我已经修复了返回类型中的拼写错误。 - Matthew Watson

0

这个扩展方法可以很好地完成工作,而且代码简洁明了:

public static class ListExtensions
{
    /// <summary>
    /// Finds the indices of all objects matching the given predicate.
    /// </summary>
    /// <typeparam name="T">The type of objects in the list.</typeparam>
    /// <param name="list">The list.</param>
    /// <param name="predicate">The predicate.</param>
    /// <returns>Indices of all objects matching the given predicate.</returns>
    public static IEnumerable<int> FindIndices<T>(this IList<T> list, Func<T, bool> predicate)
    {
        return list.Where(predicate).Select(list.IndexOf);
    }
}

请查看工作演示


警告:如果列表中有重复的条目(由于“IndexOf”),则此方法无法正常工作。 - Gunther Struyf

0

rgripper答案进行了小变化,

List<int> mylist = new List<int> { 10, 11, 23, 34, 56, 43 };
List<int> newList = mylist.Select((v, i) => new { v, i })
                        .Where(x => x.v > 23)
                        .Select(x => x.i).ToList<int>();

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接