I need to sort the data in a Hashtable by a property of the object added to the collection. how to do that? my project uses .NET 2.0, so I can't use any features that do not work by default in .NET 2.0 runtime (I may be able to use some of the C# 3.0 features that will work on .NET 2.0 without adding references to any new dlls). all the objects added to hashtable are of the same type. If I use SortedList and pass Hashtable to it (through constructor), then it sorts only by keys, is there a way to pass custom sorting logic to it?
if you are bound to .NET 2.0 you can use IComparer.
http://codebetter.com/davidhayden/2005/02/27/implementing-icomparable-for-sorting-custom-objects/
a Hashtable is definetly the wrong datastructure if you want to sort something.
#Snoopy said IComparer, that is indeed what you need. Take a look at SortedDictionary.
Take a look at the drawbacks of a hash table. Then look at the advantages and determine if you are using the right data structure. If you very rarely sort, then you may be using the right data structure. In this case, sorting will require you enumerate the values and put them into a list. If sort if frequent, consider moving to a different data structure, like a search tree. If you rarely do lookups/searches, I would consider using an ordinary list.
One option, if you want to stick to creating a sorted list from the contents of a Hashtable, is to write a subclass of IComparer, overload the Compare method as needed, and create a Sorted list using:
SortedList s = new SortedList( new MyIComparer() );
Then add the elements of your Hashtable to the list accordingly.
Related
I have a predefined data format, which requires me to have an object like this:
settings:{
settingA:'someValueFromSql',
settingB:'someValueFromAD'
settingC:'someValueFromConfigFile',
settingD:'someValueFromReflection',
settingE:42,
...
}
This settings object is in fact a huge mess of data stitched together from many different sources, but this is how the data is expected by the frontend. I'd like to put the "get/process all data from one source" in a function each, and tape the object together in the end.
So I would have one object
sqlSettings:{
settingA:'someValueFromSql',
settingG:'someOtherValueFromSql',
...
}
returned by function a, and an object
adSettings:{
settingB:'someValueFromAD',
settingV:'someOtherValueFromAD',
...
}
returned by function b, and an object
settings includes adSettings, sqlSettings
where, with at most two simple steps, I can "join together" both objects into a flat third object.
Is this possible with fixed-size objects, without using a generic Dictionary, or am I barking up the wrong tree?
(I'm sure this question was already asked on SO, but I guess I don't find the right words)
It's not possible with a "normal" object, but you can do it with an ExpandoObject and the dynamic keyword. But you need at least .net 4.0
dynamic settings = new ExpandoObject();
//If you try to assign a property that doesn't exist, it is added to the object.
settings.SettingA="sfgd"
Anyway I discourage using this approach. why you don't want to use a IDictionary<string, object> or better a IDictionary<string, MyCustomSettingObject>
--------------------UPDATE---------------------
if the only thing that stops you from using a dictionary is the serialization you can implement the IXmlSerializable Interface and ouput the xml you like:
Proper way to implement IXmlSerializable?
If those partial setting objects have fixed size (meaning fixed number of properties), then you can definitely create a flat object with e.g. only properties to fit all the values in. Then to ease your work, you can try to use Automapper to map the partial objects to the "grouped" object.
http://automapper.codeplex.com/
Otherwise, you will have to stick with the dictionary.
I have a class (SomeClass) which contains a property Name of string type. And I need to store an array of that class and find its items by their names. For this purpose there are two types of collections: KeyedCollection and Dictionary. My question is: What difference between them and in such case It is better to use KeyedCollection and Dictionary? Thanks for any help in explanation.
None of the previous comments address the most important difference between the two:
KeyedCollection keeps your items in the order in which they are added (the first item added is at index 0 and the last added is at the last index). Dictionary does not (or at least it is never guaranteed to do so).
This extra benefit of KeyedCollection does have a small performance cost. Under the covers, you pay the cost of maintaining both a Dictionary and a List.
Here is good explanation about differences between Dictionary and KeyedCollection: http://geekswithblogs.net/NewThingsILearned/archive/2010/01/07/using-keyedcollectionlttkey-titemgt.aspx
Main points are:
KeyedCollection is abstract, so you can't use it directly.
KeyedCollection is useful for cases, when key is in entity itself, then you can encapsulate key retrieval within collection implementation.
There are generic implementations for KeyedCollection (not in the framework though), which allow you to paste key retrieval delegate in collection constructor, so you don't have to repeat it each time you add item.
Update: as long as original link to article was removed, adding link to web archive: https://web.archive.org/web/20200228045828/http://geekswithblogs.net/NewThingsILearned/archive/2010/01/07/using-keyedcollectionlttkey-titemgt.aspx
A KeyedCollection allows mutable keys and ways to manage change in key. Dictionary does not allow changes to key. Secondly, if you have a collection which needs lookup, the logic to extract key from entity remains in one place - whereas maintaining dictionary will need to put key extraction logic at each place where items are added/removed from dictionary.
By default a KeyedCollection creates a Dictionary under the covers.
If the Key also has meaning as part of the Value and also defines uniqueness then that is the purpose of a KeyedCollection.
If you want to modify the dictionary backing then use this ctor:
protected KeyedCollection(
IEqualityComparer<TKey> comparer,
int dictionaryCreationThreshold)
A KeyedCollection should be used when the key is on the item itself.
By default, KeyedCollection is a Collection<TItem> wrapper around a dictionary. When you use small collections and/or you prefer retrieving items directly, the KeyedCollection provides a constructor that takes a dictionaryCreationThreshold parameter, that indicates at what collection count to switch to Dictionary.
Another aspect in KeyedCollection is that you can choose to switch the key property (as long as their types match). This can be good for double keyed items etc.
Performancewise, I don't think wrapping a dictionary has much overhead except if you generate a bunch of KeyedCollection instances, or if you use really large collections (there are some internal null checks to determine if there is a dictionary).
One thing I'd hope to see in KeyedCollection is unabstracting it, but you can make a generic concrete type just as easy.
You can't use KeyedCollection because it's abstract: http://msdn.microsoft.com/en-us/library/ms132438.aspx. This means you can't create an object of it.
Is there a simple way to have a bindinglist composed of several bindinglists? i.e. that is the "view" of the lists.
That is to say: I have 3 lists (list1,list2,list3). I want a list that is always the union of the 3 listx (we can suppose that no object is contained in 2 different lists).
Certainly, I can succeed in using the ListChange property but maybe there is a smarter way to do this?
To do this you would need to create your own type, implement IList, IBindingList (and ideally IBindingListView), and optionally ICancelAddNew and IRaiseItemChangedEvents. You'd also need either a public non-object indexer (public T this[int index] {get;}) or ITypedList.
From having done things similar to this, I strongly advise you; don't, unless this is really important. It would be more pragmatic to copy the references into a new BindingList<>.
Also; with new items; which list would it go into?
Have you looked into the CompositeCollection class?
Depending on what you're trying to do, it might help: its purpose is to combine multiple collections into a single collection (typically for display/binding purposes). So, you could create a CompositeCollection and add your three BindingList instances to it. The CompositeCollection will automatically update to include the members of the "child" lists.
I'm iterating through a List<> to find a matching element. The problem is that object has only 2 significant values, Name and Link (both strings), but has some other values which I don't want to compare.
I'm thinking about using something like HashSet (which is exactly what I'm searching for -- fast) from .NET 3.5 but target framework has to be 2.0. There is something called Power Collections here: http://powercollections.codeplex.com/, should I use that?
But maybe there is other way? If not, can you suggest me a suitable custom collection?
In .NET 2.0 instead of a HashSet<T> you can use a Dictionary<K, V>.
Dictionary uses the hash code to perform key lookups so it has similar performace to the HashSet. There are at least two approaches:
Create a custom class or struct containing the Name and Link and use that as the key in the dictionary, and put the object as the value.
Store the entire object as the key and provide a custom equality comparer that only looks at the Name and Link member, and set the value to null.
The second method is very similar to how you would use a HashSet if it were available.
How about this:
Custom class/collection wich will held List of objects and two dictionaries, one for the name and one for the link. Both of them will have a int value wich will be the index of object. I think that in that case I will only need to check if there is such int value of name dictionary that equals link dictionary int.
Is this a good approach?
What is the best way to store a map of key object to a collection of value objects?
I could use
Dictionary<KeyType, Collection<ValueType>>
but that approach tends to involve a lot of housekeeping, and clutters up the code.
The Lookup type is almost the result I'm looking for, but it's immutable and has no constructor. I could create my own custom class, but it seems like it should exist in the framework somewhere.
That's about your best answer. It's pretty common to use Dictionary<KeyType, ICollection<ValueType>>. Using the var keyword to declare your local variables is the best way to tidy up.
Other than that, your only option is creating a MultiDictionary<T,K> type. You could also call it Lookup and put it in your own namespace?
Edit: Google says you should take a look at this for an existing implementation: Multi-value Dictionary C# source code (.NET 3.5). BSD2 license means you can use it for commercial apps with at attribution. :)
You could also, as for tidying, alias the specific generic type:
using MultiDictionary = Dictionary<string, ICollection<int>>;
Then later:
var foo = new MultiDictionary();
In .NET 3.5, there is ILookup<Tkey,TValue> and Lookup<TKey,TValue> that serves this purpose; however, the default implementation is immutable. I wrote a mutable variant for MiscUtil; EditableLookup<TKey,TValue> - which does exactly what you want.