Keeping track of indices in a List

Hello!I was wondering if there is any simple way of keeping track of a List that gets reordered randomly.

For instance we have a List of integers :

var MyList : List. = new List.();

Let’s say this list has 5 elements : 12 , 3 , 44 , 33 , 87.
And over time it changes…For instance other elements get inserted,some get removed,some get moved etc…
So in the end it looks like : 3 , 656 , 22 , 12 , 44 , 87

Is there a simple way (other than actually keeping track of what changes the List) to keep track of the index of the initial element 2 (which is 44),for example, that at the end got to be at index 4?

Something like linking the index of that element to an external variable or displaying it like an external variable,so var TrackIndex : int will always be equal to the index of that element.Is it possible without using the update function and stuff like that?

Thanks in advance!

use a dictionary

HashTable, or better Dictionary (which is a more efficient HashTable, HashTable is .Net 1.0 stuff):

Instead of being a list, it’s a collection. You have keys to the collection, a key returns a given value associated with that key. You can use any type as the key, and any type as the return (HashTable doesn’t have types for each, this is why Dictionary is better, it uses generics and is type safe… HashTable remains for backwards compatibility, and if you want to allow ANYTHING to be a key and value… though using Object as the types on a dict allows that too).

example:

var dict = new Dictionary<string, int>();
dict["a"] = 44;
dict["c"] = 12;
dict["b"] = 100;

Debug.Log(dict["a"]);

Just to clarify what you’re asking. There’s a function in the List class called IndexOf() which takes in the value of an item and returns its index in the List, if the value exists in the list. If multiple items have the same value, then the function returns the index of the first item. This function is a O(n) operation, which can be quite costly if the list is large and you are calling it often. You’re asking if there is an automatic way to get the IndexOf() in one-shot, without searching for the item’s index. The answer is, no. You’re going to have to keep track of that information yourself if you want to obtain it faster than IndexOf() can do.

Keep in mind that there isn’t anything magical going on inside the List class, it simply maintains a one-dimensional array. It doesn’t know where 44 is in the list any more than you do. When an item is removed from the list, all items that are above that index are moved down one index to fill in the gap. When an item is added to the list, memory is allocated if necessary and the list is copied to the new memory, and all items above that index are moved up one to make a space for the new item. The index of any given item in a List is never guaranteed and should not be relied on for item retrieval.

If your list is very dynamic and if you need to know where an item exists relative to other items in the list, then you’ll need to keep track of that yourself. You might consider implementing a linked list instead. See MSDN .NET documentation for the LinkedList class and LinkedListNode class, or roll your own code. Remember, this still doesn’t automatically keep track of “order”, you will still be required to maintain order as a variable with each item in the list, but a linked list makes this easier to do and suffers considerably less overhead for insert/delete/move for large lists.

Thanks guys…i guess i’ll have to work a way around it.
Thanks,but dictionaries and hashtables wouldn’t really help because the order of that list is really important.Converting the list to a dictionary would just give me the ability to set the index,so to speak,correct?

That’s what i feared…Recently i opened a thread about “linked variables” and i was answered that it actually is possible to kinda link 2 variables trough a class.
I thought that it might be possible to link the index of an element to a variable in the same manner.

Thank you for the answers!

Edit : I can’t use IndexOf,since my List has many elements and i would need to use that function very often.

You can of course write your own collection class that keys and orders your collections the way you want.

Essentially combining the key lookup AND the ordering of a list so you can sort easily. You’d just implement both IDictionary and IList.

Note, System.Collections.Specialized has an OrderedDictionary for this…

But if it doesn’t suit your needs, writing your own is fairly simple. I write custom collections all the time for various tasks…

Wow!A List that actually has keys?That’s exacly what i needed!Sorry because i couldn’t explain the real purpose of my List,but it’s very hard to…
That’s what i needed…An extra indentifier for my list.
I was really thinking now if i could bind them together myself,but if it is already implemented…

One more question : Are they extremly slow or expensive?Because it doesn’t specify on http://msdn.microsoft.com

Thank you!

http://c-cpp.r3dcode.com/files/mono/2/10.2/mcs/class/System/System.Collections.Specialized/OrderedDictionary.cs

Well here’s a source code saying it’s the mono implementation of OrderedDictionary (can’t say for certain, but it looks about right with how it’d be done).

Note it basically contains both a Dictionary AND a List (specifically a HashTable and an ArrayList as this is the non-generic implementation…).

This means you have twice the object size going on (a list AND a table). It also means sorting algorithms that pertain to sorting by index will be faster than sorting by key. (key sorting will require modifying both table and list, where as index sorting will only sort the list).

It’s relatively efficient… how large do you expect it to be? Unless you have thousands of entries, you shouldn’t notice anything.

Ah,i see…Then i might end up making my own “Generic OrderedDictionary”,since i only need the Key to be an integer and the value integer aswell…so no need for extras.
(I see that in the case of OrderedDictionaries it doesn’t work to put the key as an Int because it will recognize it as an index.Converting it to a float,however,makes it work without problems)

The size might vary…Somewhere between 0 and 1024 or 2048.Not more for sure.I guess i can afford that for now.

Thanks again for all the help,definitely now i have a direction.