Retaining index of an item
-
I've been working on a project for the past week or so, and it's come to my attention that I need a method of being able to 'track' the index of an item within a collection. A prime example of what I'm trying to achieve is the
System.Windows.Forms.ListViewItem
class, which retains anIndex
property which is always matched to the actual index within the collection of aSystem.Windows.Forms.ListView
. A method I've been trying is iterating through the collection any time an update ends and updating each item individually. However, I have noticed that this takes a ridiculously long time when we begin achieving millions of rows. Items are removed from the collection, but then after the update has finished, it has to iterate through the collection to synchronize the indices. Other than using LINQ on the collection from the individual item, can anyone suggest a better way to maintain the index of the item within the list? -
I've been working on a project for the past week or so, and it's come to my attention that I need a method of being able to 'track' the index of an item within a collection. A prime example of what I'm trying to achieve is the
System.Windows.Forms.ListViewItem
class, which retains anIndex
property which is always matched to the actual index within the collection of aSystem.Windows.Forms.ListView
. A method I've been trying is iterating through the collection any time an update ends and updating each item individually. However, I have noticed that this takes a ridiculously long time when we begin achieving millions of rows. Items are removed from the collection, but then after the update has finished, it has to iterate through the collection to synchronize the indices. Other than using LINQ on the collection from the individual item, can anyone suggest a better way to maintain the index of the item within the list? -
I've been working on a project for the past week or so, and it's come to my attention that I need a method of being able to 'track' the index of an item within a collection. A prime example of what I'm trying to achieve is the
System.Windows.Forms.ListViewItem
class, which retains anIndex
property which is always matched to the actual index within the collection of aSystem.Windows.Forms.ListView
. A method I've been trying is iterating through the collection any time an update ends and updating each item individually. However, I have noticed that this takes a ridiculously long time when we begin achieving millions of rows. Items are removed from the collection, but then after the update has finished, it has to iterate through the collection to synchronize the indices. Other than using LINQ on the collection from the individual item, can anyone suggest a better way to maintain the index of the item within the list?I'm with Ravi on that, what keeps you from adding / updating the information of an item at the time you access it by using
IndexOf
()?I will never again mention that Dalek Dave was the poster of the One Millionth Lounge Post, nor that it was complete drivel.
-
I believe an issue with using
IndexOf
is that if the same item is added more than once to the collection, the value returned byIndexOf
will be the first index only. The item I'm storing in the collection could be added multiple times. For instance:public class MyClass
{
public string Text { get; set; }
public int Index { get; set; }
};private void ExampleList()
{
// create the list
List<MyClass> list = new List<MyClass>();// create an instance MyClass first = new MyClass() { Text = "Hello" }; // append this item into the list twice list.Add(first); list.Add(first); // create a second instance MyClass second = new MyClass() { Text = "Goodbye" }; // append this item into the list list.Add(second); // if the Index property were to use the IndexOf method from the parent list, // below would be the results: System.Diagnostics.Debug.WriteLine(list\[0\].Index); // 0 System.Diagnostics.Debug.WriteLine(list\[1\].Index); // 0 System.Diagnostics.Debug.WriteLine(list\[2\].Index); // 1
}
Obviously if multiple instances of the same object is going to be an issue, I could re-factor my code to prevent multiple additions, but it'd be preferable if the developer had the option to add the same item twice. Otherwise, am I restricted entirely to updating the
Index
property on each collection change? I just wondered if there was some work-around (ie, creating an index array or using some sort of indexing engine built into the framework.) Thanks -
I believe an issue with using
IndexOf
is that if the same item is added more than once to the collection, the value returned byIndexOf
will be the first index only. The item I'm storing in the collection could be added multiple times. For instance:public class MyClass
{
public string Text { get; set; }
public int Index { get; set; }
};private void ExampleList()
{
// create the list
List<MyClass> list = new List<MyClass>();// create an instance MyClass first = new MyClass() { Text = "Hello" }; // append this item into the list twice list.Add(first); list.Add(first); // create a second instance MyClass second = new MyClass() { Text = "Goodbye" }; // append this item into the list list.Add(second); // if the Index property were to use the IndexOf method from the parent list, // below would be the results: System.Diagnostics.Debug.WriteLine(list\[0\].Index); // 0 System.Diagnostics.Debug.WriteLine(list\[1\].Index); // 0 System.Diagnostics.Debug.WriteLine(list\[2\].Index); // 1
}
Obviously if multiple instances of the same object is going to be an issue, I could re-factor my code to prevent multiple additions, but it'd be preferable if the developer had the option to add the same item twice. Otherwise, am I restricted entirely to updating the
Index
property on each collection change? I just wondered if there was some work-around (ie, creating an index array or using some sort of indexing engine built into the framework.) ThanksChris Copeland wrote:
Obviously if multiple instances of the same object is going to be an issue
You didn't add multiple instances; you added a single object to the list twice. Now, you'd have to loop the list to find ALL the objects if there can be multiple - but then the property "Index" on the object is erroneous - if the object can be added to the list twice, then "Index" should return an array, returning 0 and 1 as the indexes where it is to be found. Alternatively;
public class MyClass: ICloneable
{
public string Id = Guid.NewGuid().ToString();
public string Text { get; set; }public override string ToString() { return Text; } public override int GetHashCode() { return Id.GetHashCode(); } public object Clone() { return new MyClass() { Text = this.Text }; }
}
Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
-
Chris Copeland wrote:
Obviously if multiple instances of the same object is going to be an issue
You didn't add multiple instances; you added a single object to the list twice. Now, you'd have to loop the list to find ALL the objects if there can be multiple - but then the property "Index" on the object is erroneous - if the object can be added to the list twice, then "Index" should return an array, returning 0 and 1 as the indexes where it is to be found. Alternatively;
public class MyClass: ICloneable
{
public string Id = Guid.NewGuid().ToString();
public string Text { get; set; }public override string ToString() { return Text; } public override int GetHashCode() { return Id.GetHashCode(); } public object Clone() { return new MyClass() { Text = this.Text }; }
}
Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
I'd not thought about adding a unique identifier property. That makes much more sense than actually indexing the position of the item. I suppose the chances of collision are exceptionally low too when using
Guid
. Thanks for the assistance, I'll give this a try when I land home! -
I believe an issue with using
IndexOf
is that if the same item is added more than once to the collection, the value returned byIndexOf
will be the first index only. The item I'm storing in the collection could be added multiple times. For instance:public class MyClass
{
public string Text { get; set; }
public int Index { get; set; }
};private void ExampleList()
{
// create the list
List<MyClass> list = new List<MyClass>();// create an instance MyClass first = new MyClass() { Text = "Hello" }; // append this item into the list twice list.Add(first); list.Add(first); // create a second instance MyClass second = new MyClass() { Text = "Goodbye" }; // append this item into the list list.Add(second); // if the Index property were to use the IndexOf method from the parent list, // below would be the results: System.Diagnostics.Debug.WriteLine(list\[0\].Index); // 0 System.Diagnostics.Debug.WriteLine(list\[1\].Index); // 0 System.Diagnostics.Debug.WriteLine(list\[2\].Index); // 1
}
Obviously if multiple instances of the same object is going to be an issue, I could re-factor my code to prevent multiple additions, but it'd be preferable if the developer had the option to add the same item twice. Otherwise, am I restricted entirely to updating the
Index
property on each collection change? I just wondered if there was some work-around (ie, creating an index array or using some sort of indexing engine built into the framework.) ThanksChris Copeland wrote:
The item I'm storing in the collection could be added multiple times.
This wasn't obvious (to me) in your original post. One solution would be to write an extension method
IList<T>.IndicesOf(T)
that would return anIEnumerable<int>
of indices. But clearly, this doesn't scale when you have a large number of items. /raviMy new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com