How to get Index of an Item in ICollection<T>
Asked Answered
F

2

10

I have this list of cars

ICollection<Cars> Cars

and I also have a single car object, which I know is in the ICollection how do I get the index/position of the car in the list? I need to add it to a list of strings

This is what I have so far:

var index = cars.Where(b=> b.Id == car.id).Single().iWantTheIndex
stringList.Add(index)

Any ideas?

Filose answered 15/11, 2017 at 15:13 Comment(10)
LINQ does not have a FindIndex() method.Demarche
var index = cars.Select((b, i) => new { car = b, index = i }).Single(b => b.car.Id == car.id).index;Radford
Does ICollection<T> even have indexes? How do you get an element from Cars based on its index?Devout
@Devout No, ICollection's don't necessarily have indexes.Frenum
@BlakeThingstad: Clever, though that's adding an artificial index based on whatever the current state of cars is. The system provides no guarantee that the same "index" would match the same object in any future operation. One could, on the very next line of code, attempt to fetch the same object from cars based on that index (likely using .Skip() and .First() or something of that nature) and get a completely different object.Devout
@Devout would it work if the collection was initialized as a collection that does index its objects (such as List)? The OP would still want to seriously consider changing their code structure, but just wondering.Radford
@BlakeThingstad: Directing to Servy's answer below, yes. If the OP wants to use an ordered collection, ICollection<T> is the wrong type to use. The OP is looking for IList<T>.Devout
@BlakeThingstad If you're going to require the implementing type to be an ordered collection that requires all items to have a meaninful index, then actually require that by using an interface whose contract requires those things (IList<T>) rather than one that doesn't (ICollection<T>). It's a very bad idea to use an interface whose contract doesn't actually specify all of the things you need, and to just hope that anyone using that code knows that they're actually supposed to provide specific types of implementations.Frenum
An Index is usually a number, so what exactly do you mean by adding it to a list of strings?Romanic
I get it I get it now.... my question was slightly floored from the start.... a Icollection is not a listFilose
F
21

If you want to use an indexed collection then you should use IList<T>, not ICollection<T>. An ICollection<T> is something that you can enumerate, add and remove items for, and get the count of, that's all. An IList<T> is a collection in which the items are in a specified order, and can be accessed based on their position in the list.

Because an ICollection<T> doesn't necessarily represent an ordered collection, you cannot get a meaningful "index" of an item. Items don't necessarily have a position.

Frenum answered 15/11, 2017 at 15:22 Comment(0)
S
1

This will give you the index of the current iteration:

var index = cars.Select((c, i) => new{ Index = i, Car = c })
                .Where(item => item.Car.Id == car.id)
                .Single()
                .Index;

stringList.Add(index);

Please note that the next iteration may have a different order (depending on the actual implementation of your ICollection<>) and may result in a completely different index, so be careful what you use this index for.

Stans answered 15/11, 2017 at 15:28 Comment(6)
This index doesn't provide anything of value though. The collection isn't ordered. It could have an entirely different index the next time you enumerate it.Frenum
@Frenum You are right, next time you call this, depending on the actual implementation behind the interface, you may just get a different index. However, it's not up to me to say whether the current index of that car is of any value. I can only say this is a way to get it.Stans
But you don't have the current index of the value. You have the value of what the index used to be in a sequence that can never be accessed again. You don't actually have the index of the item in the collection.Frenum
@Frenum You are right, current was the wrong choice of words. Last would be a better description.Stans
@Stans Can you add some commentary onto the answer so that it can be of more value to others in the future?Battle
@DrRobLang Done :)Stans

© 2022 - 2025 — McMap. All rights reserved.