0

I need to find the index of a particular item with TValue list using Linq methods without using looping. I have tried to find index by comparing single TValue with a IEnumerable collection of Tvalue like below code

 int idx= list.Select((elem, index) => new { elem, index }).First(p => p.elem == item).index;

With this, I am getting the following error

CS0019 Operator '==' cannot be applied to operands of type 'TValue' and 'TValue'

I have also tried Equals with this code but that too doesn't return exact index value.

 int idx= list.Select((elem, index) => new { elem, index }).First(p => p.elem.Equals(item)).index;

Here, the list is a collection of TValue with 5 items and item is a TValue with a single item whose index is to be found within the list. Find the structure in below image

enter image description here

Please suggest a way to find index by comparing both TValue

Regards,

Keerthana.

keerthana
  • 117
  • 10
  • Can you show the class where TValue comes from? – Magnus Jun 29 '20 at 07:44
  • Please edit the question, and add a description of the relevant parts of your `list`. Also, your Select statement is an unusual overload of `IEnumerable<...>.Select`, can you give us the signature of this overload? – Harald Coppoolse Jun 29 '20 at 07:56
  • TValue Item will be received as { Id = "1", Text = "txt" }; – keerthana Jun 29 '20 at 08:07
  • @keerthana try to compare by `id`:like `.First(p => p.elem.Id == item.Id)` – Mohammed Sajid Jun 29 '20 at 08:11
  • Why can't you just use int ```idx= list.IndexOf(item)```? – Döharrrck Jun 29 '20 at 09:11
  • Yes, I tried IndexOf it returns -1 which is incorrect – keerthana Jun 29 '20 at 09:16
  • You have to make your object read-only, override `Equals` & `GetHashCode` before you can implement the `==` and `!=` operator overloads. – Enigmativity Jun 29 '20 at 09:30
  • Is the item you are looking for really an instance which is included in the list or are you looking for an item with the same Id and Text? In the latter case it is clear that IndexOf will return -1 and ```int idx= list.IndexOf(elem => elem.Id == item.Id && elem.Text == item.Text);``` should work comparing the properties as sgmoore suggested. – Döharrrck Jun 29 '20 at 09:43
  • Also this might be helpful: https://stackoverflow.com/questions/8982645/how-to-solve-operator-cannot-be-applied-to-operands-of-type-t-and-t. You have to use EqualityComparer class to compare generic types. – Döharrrck Jun 29 '20 at 09:43

2 Answers2

0

You can try the this code

int idx= list.Select((elem, index) => new { elem, index }).First(p => EqualityComparer.Default.Equals(p.elem item).index

Gopi G
  • 17
  • 5
-1

Not everything can be compared directly. For example

var item1 = new KeyValuePair<int, string>(1, "text");
var item2 = new KeyValuePair<int, string>(1, "text");

var theSame = (item1 == item2);

would give an error of

CS0019 Operator '==' cannot be applied to operands of type 'KeyValuePair<int, string>' and 'KeyValuePair<int, string>'

So, if you can't compare one TValue with another, then you may need to compare each element individually, ie

 int idx= list.Select((elem, index) => new { elem, index })
         .First(p => p.elem.Id == item.Id && p.elem.Text == item.Text).index;
sgmoore
  • 15,694
  • 5
  • 43
  • 67
  • Added image in the description for the structure of list in which I try to find index for an item. item.Id and p.elem.Id cannot be retrieved here. And this results in the following error. item.Id error CS1061: 'TValue' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'TValue' could be found (are you missing a using directive or an assembly reference?) – keerthana Jun 29 '20 at 09:59
  • When trying to remove using normal Remove method of Lists. The item exists within the list as the first item but it returns false. item {WebApplication1.Pages.RemoveItem.DataModel} WebApplication1.Pages.RemoveItem.DataModel Id "1" string Text "Artwork" string list.Remove(item) false bool - list Count = 6 System.Collections.Generic.List - [0] {WebApplication1.Pages.RemoveItem.DataModel} WebApplication1.Pages.RemoveItem.DataModel Id "1" string Text "Artwork" string – keerthana Jun 29 '20 at 10:37