How to Get Index Using Linq

How to get index using LINQ?

An IEnumerable is not an ordered set.

Although most IEnumerables are ordered, some (such as Dictionary or HashSet) are not.

Therefore, LINQ does not have an IndexOf method.

However, you can write one yourself:

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

Finding index from Select query in Linq

var result = 
link.Select((x, i) => new { value = Math.Abs(x.Prop1 - x.Prop2), index = i })
.OrderByDescending(x=>x.value)
.FirstOrDefault();

var indexValue = result?.index;
var maxValue = result?.value;

Here this is working.

Get index of object in a list using Linq

You don't need to use LINQ, you can use FindIndex of List<T>:

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

How to grab the index from a list using LINQ

The question can be rephrased to "How do I get index of element in IEnumerable". Here is the answer: How to get index using LINQ?
Here is how to use it:

int rank = lstTeamSales.OrderBy(x => x.TotalSales).FindIndex(x => x.userID == currentUserID);

And this will be slightly more efficient than Select based approaches.

Update

It appears .FindIndex is not supported for LINQ. Any idea how to implement that functionality?

I may have figured it out testing it now. I just added .ToList() after the ORderBy().

No-no-no-no! It kills the whole idea :( The idea is to add extension method FindIndex to IEnumerable. And then use it. See example:

static class FindIndexEnumerableExtension
{
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;
}
}

class YourClass
{
void YourMethod()
{
lstTeamSales.OrderBy(x => x.TotalSales).FindIndex(x => x.UserID == currentUserID);
}
}

After you define class FindIndexEnumerableExtension with FindIndex extension method, you can use this method anywhere in your code. All you need is just add using directive with module where FindIndexEnumerableExtension is defined. This is, basically, how LINQ works.

If you don't want to go with this solution then, at least, convert lstTeamSales to List before sorting it. And sort it using List<>.Sort() method.

LINQ indexOf a particular entry

Well you can use Array.IndexOf:

int index = Array.IndexOf(HeaderNamesWbs, someValue);

Or just declare HeaderNamesWbs as an IList<string> instead - which can still be an array if you want:

public static IList<string> HeaderNamesWbs = new[] { ... };

Note that I'd discourage you from exposing an array as public static, even public static readonly. You should consider ReadOnlyCollection:

public static readonly ReadOnlyCollection<string> HeaderNamesWbs =
new List<string> { ... }.AsReadOnly();

If you ever want this for IEnumerable<T>, you could use:

var indexOf = collection.Select((value, index) => new { value, index })
.Where(pair => pair.value == targetValue)
.Select(pair => pair.index + 1)
.FirstOrDefault() - 1;

(The +1 and -1 are so that it will return -1 for "missing" rather than 0.)

LINQ selecting items from a list and saving their indices from the original list

You have to remember indexes. It can be done via Select overload

var selectedItems = originalList
.Select((e, index) => new { e, index })
.Where(p => p.e > 5)
.ToList();

Get an index array from where using Linq - C# Unity3D

indexesOfTopPoints = polygonCollider2D.points.Select((x, index) => index)
.Where(x => polygonCollider2D.points[x].y > lowestY).ToArray();

Get index of matching value in List using LINQ

It's possible to achieve with LINQ by using the fluent syntax since there's an overloaded version of the Select extension method that lets you get the index of the items.

Try this approach:

Dim test As Integer = 5
Dim query = widgetList.Select(Function(o,i) New With { .Widget = o, .Index = i}) _
.FirstOrDefault(Function(item) item.Widget.Foo = test)
If query Is Nothing
Console.WriteLine("Item not found")
Else
Console.WriteLine("Item found at index {0}", query.Index)
End If

In the Select I'm projecting the Widget as is, using o, and the i parameter represents the index. Next I use FirstOrDefault with a predicate to evaluate Foo (you could've used Where followed by FirstOrDefault, but this is shorter). You should use FirstOrDefault instead of just First in case none of the items are found; FirstOrDefault will return null if nothing is found, whereas First would throw an exception. That's why the next step is to check the result and make sure it isn't null.



Related Topics



Leave a reply



Submit