简体   繁体   中英

Is dictionary the best data structure for this case?

I have the need to have a

Dictionary< long, List<Person> > 

Person has ID and Value properties.

I want to be able to get the List by an ID and also be able to find a person with a specific ID easily from this collection.

Is Dictionary< long, Dictionary<long, string> >

the only good fast way of getting this done? Or is there another simpler or better data structure to use in this case?

EDIT: Also, for a lookup if i ONLY have the person ID then I would still have to loop through the original dictionary to get that value. Thanks,

I would just use a Dictionary<long, List<Person>> (or maybe just Dictionary<long, IEnumerable<Person>> ) and only change the structure if speed is a measurable issue. Then a lookup would just be:

outerDict[listID].First(p => p.ID == personID);

A few drawbacks of using Dictionary<long, Dictionary<long, Person>> :

  • If the ID of a person changes, you'd need to intentionally move it to a different bucket in the Dictionary (there's no framework structure that does this for you)
  • If you just want a list of Person s, or need to look up people by an attribute other than ID , then the structure just makes it a bit harder to traverse the inner collection.

If neither of those is a concern, then Dictionary<long, Dictionary<long, Person>> would definitely be faster, but you won't know how much faster until you try both and measure them.

Based on your edit (and assuming the List ID and Person ID never change for a Person), another option may be to load all of the data into a flat list and create lookups by ListID and a dictionary by PersonID:

List<Person> people = {load list};
var peopleByListID = people.GroupBy(p => p.ListID).ToLookup();
var peopleByID = people.ToDictionary(p => pID, p => p);

That way you can use whatever structure best fits your needs. There's some additional overhead for creating the lookup and dictionary, so unless you're needing to constantly go back to the original source these would provide significant performance benefit in the searches.

You essentially have a two-keyed dictionary. You need to have two long values to access the value of your dictionary. Simply create a composite object representing both of these ID values to be the key to your dictionary:

Dictionary<Tuple<long, long>, Person>

By using a single flattened dictionary, rather than nested dictionaries, you prevent the fragmentation in memory and limit the dictionary's overhead. If you would like to improve readability a bit, you can create your own custom object to represent the key (just be sure to override GetHashCode and Equals effectively) instead of using a Tuple .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM