1

What collection type would I use in C# for an array where the indexes are non-consecutive (but are only added in ascending order), and I need access both by index and by place (e.g. "consecutive index")?

For example, if I add the objects A, B and C with indexes 2, 4 and 7, I need to access by index (2/4/7) or by place (1/2/3 or 0/1/2 both work).

3
  • 2
    Are A,B and C or 2,4 and 7 unique? Commented Feb 17, 2013 at 20:21
  • Tying together a dictionary for key lookup and a list for order is probably your best bet. I think you could probably do something using a k-d tree for this, although I don't know much about them, and I think that would be a bit overkill for this. Possibly if you want to get down and dirty it might be made a little more efficient by reimplementing parts of the Dictionary class, but I think that would be a bad idea. Commented Feb 17, 2013 at 20:44
  • @TimSchmelter In my current case they are unique Commented Feb 17, 2013 at 20:55

2 Answers 2

2

You should use a Dictionary to store the objects for access by their index, but you'll also need some kind of List to store the 'place' as Dictionary doesn't store place. Join these together in your own class and handle adding as one operation to make sure they are in sync.

If you only want to use one, you can use the List and loop over it to look up the key, but it will take linear O(N) time.

Edit

As Matthew Strawbridge points out, the BinarySearch method will find the element in O(log N) so you can skip using the dictionary.

Sign up to request clarification or add additional context in comments.

1 Comment

Even if just using a List of pairs, because it's sorted you can use List<T>.BinarySearch to look up an element in O(log N) time.
1

Use a Dictionary:

using System.Collections.Generic;

Dictionary<int, type> dict = new Dictionary<int, type>();

// Add values:
dict.Add(2, A);
dict.Add(4, B);
dict.Add(7, C);

// by index:
var A = dict[2];
var B = dict[4];
var C = dict[7];

// by place:
var A = dict.ElementAt(0);
var B = dict.ElementAt(1);
var C = dict.ElementAt(2);

9 Comments

I'm not sure order of insertion is guaranteed to be order of storage with a Dictionary<K,T>. The "by index" would work guaranteed, but I'm not sure about the "by place". If you want to guarantee indexed access, use the OrderedDictionary<K,T> instead.
Insertion order is certainly not guaranteed. ElementAt is a hack that works on any IEnumerable. A red flag by itself.
It still is the most viable option, excluding making a IEnumerable subclass.
@MicaelBergeron why would it be viable if it returns the wrong results? It can return any order at all.
Correct, ElementAt() gives the values by order of insertion, but as he said: "indexes are non-consecutive (but are only added in ascending order)", so for this case it is suitable
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.