如何使用LINQ获取索引?

29 浏览
0 Comments

如何使用LINQ获取索引?

如何使用LINQ找到满足特定条件的第一辆车的索引?\n给定这样一个数据源:\nvar c = new Car[]\n{\n new Car{ Color=\"Blue\", Price=28000},\n new Car{ Color=\"Red\", Price=54000},\n new Car{ Color=\"Pink\", Price=9999},\n // ..\n};\n编辑:\n我能想到的解决办法是这样的,但看起来很糟糕:\nint firstItem = someItems.Select((item, index) => new \n{ \n ItemName = item.Color, \n Position = index \n}).Where(i => i.ItemName == \"purple\") \n .First() \n .Position;\n是否最好用传统的循环来解决这个问题?

0
0 Comments

LINQ是.NET Framework中的一个功能强大的编程语言集成查询(Language Integrated Query)技术。它提供了一种方便的方式来查询和操作各种数据源,如集合、数据库、XML等。然而,在使用LINQ时,有时会遇到获取索引的需求,但LINQ本身并没有提供一个IndexOf方法来获取索引。这是因为,并不是所有实现了IEnumerable接口的集合都是有序的,例如Dictionary或HashSet等。因此,为了解决这个问题,我们可以自己编写一个IndexOf方法。

以下是一个自定义的FindIndex方法的示例代码:

/// Finds the index of the first item matching an expression in an enumerable.
/// The enumerable to search.
/// The expression to test the items against.
/// The index of the first matching item, or -1 if no items match.
public static int FindIndex(this IEnumerable items, Func 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;
}

上述代码中的FindIndex方法可以在一个可枚举集合中查找第一个满足条件的元素,并返回其索引。我们还可以通过调用FindIndex方法来实现一个IndexOf方法,如下所示:

/// Finds the index of the first occurrence of an item in an enumerable.
/// The enumerable to search.
/// The item to find.
/// The index of the first matching item, or -1 if the item was not found.
public static int IndexOf(this IEnumerable items, T item)
{
    return items.FindIndex(i => EqualityComparer.Default.Equals(item, i));
}

通过调用IndexOf方法,我们可以在一个可枚举集合中查找指定元素的索引值。

虽然LINQ本身没有提供IndexOf方法,但它提供了ElementAt方法,可以根据索引获取元素。这是因为其他LINQ方法都使用了索引作为参数,这样在工具提示中可以清晰地看到委托的签名。在.NET 3.5中,Predicate、Comparison等委托被Func委托所取代,这也使得LINQ方法更加一致。

然而,LINQ与List的一致性还存在一些问题,例如FindAll(Predicate) vs. Where(Func)、Exists(Predicate) vs. Any(Func)、ConvertAll(Converter) vs. Select(Func)等。考虑到其他依赖顺序的方法(如ElementAt、First、Last、Skip等),添加一个IndexOf方法并不过分。

总之,通过自定义的FindIndex方法和调用ElementAt方法,我们可以在LINQ中获取索引值。这样就能更方便地进行查询和操作各种数据源了。

0
0 Comments

如何使用LINQ获取索引?

有时候我们需要在使用LINQ查询的同时获取元素的索引,下面介绍如何实现。

方法一:使用List的FindIndex方法

int index = List.FindIndex(your condition);

例如:

int index = cars.FindIndex(c => c.ID == 150);

方法二:对数组使用Array的FindIndex方法

需要注意的是,如果将IEnumerable转换为List,那么IEnumerable就不再是惰性的。这意味着你会强制获取它的每个元素,即使你实际上并不需要它们。

这是一个完美的解决方案,只要你使用的是唯一的条件。在其他情况下,当可能有多个元素匹配时,你将只获得第一个元素的索引,而不是索引的列表。

通过使用List的FindIndex方法或Array的FindIndex方法,我们可以在LINQ查询中获取元素的索引。但需要注意的是,如果将IEnumerable转换为List,将会强制获取每个元素,可能会影响性能。

0
0 Comments

如何使用LINQ获取索引?

有时候我们需要获取集合中满足某个条件的元素的索引。在LINQ中,我们可以使用Select方法结合匿名类型来获取元素的索引。

下面给出了几种获取索引的方法:

方法一:

myCars.Select((v, i) => new {car = v, index = i}).First(myCondition).index;

方法二:

myCars.Select((car, index) => new {car, index}).First(myCondition).index;

方法三:

myCars.Select((car, index) => (car, index)).First(myCondition).index;

这些方法都可以用于获取满足条件的元素的索引。但是需要注意的是,如果使用的是有序的集合(比如Car[]),那么标记的答案就不适用了。标记的答案返回-1,而这些方法会抛出异常。

如果想要处理没有匹配项的情况,可以使用FirstOrDefault方法。但是需要注意的是,如果myCondition不满足任何元素,调用index属性会抛出异常。

在C#6中,可以使用以下代码来处理没有匹配项的情况:

myCars.Select((car, index) => new {car, index}).FirstOrDefault(myCondition)?.index;

这样当条件不满足时,index的值会为null。

总之,使用LINQ获取索引的方法有很多种,可以根据实际需求选择合适的方法进行处理。

0