Click or drag to resize

RankedDictionaryTKey, TValue Class

Represents a collection of key/value pairs with distinct keys that can be accessed in sort order or by index.
Inheritance Hierarchy
SystemObject
  Kaos.CollectionsBtreeTKey
    Kaos.CollectionsRankedDictionaryTKey, TValue

Namespace:  Kaos.Collections
Assembly:  KaosCollections (in KaosCollections.dll) Version: 4.2.0.0
Syntax
C#
[SerializableAttribute]
public class RankedDictionary<TKey, TValue> : Btree<TKey>, 
	IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, 
	IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary, 
	ICollection, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, 
	ISerializable, IDeserializationCallback

Type Parameters

TKey
The type of the keys in the dictionary.
TValue
The type of the values in the dictionary.

The RankedDictionaryTKey, TValue type exposes the following members.

Constructors
  NameDescription
Public methodCode exampleRankedDictionaryTKey, TValue
Initializes a new dictionary instance using the default key comparer.
Public methodCode exampleRankedDictionaryTKey, TValue(IComparerTKey)
Initializes a new dictionary instance using the supplied key comparer.
Public methodRankedDictionaryTKey, TValue(IDictionaryTKey, TValue)
Initializes a new dictionary instance that contains key/value pairs copied from the supplied dictionary and sorted by the default comparer.
Public methodRankedDictionaryTKey, TValue(IDictionaryTKey, TValue, IComparerTKey)
Initializes a new dictionary instance that contains key/value pairs copied from the supplied dictionary and sorted by the supplied comparer.
Protected methodRankedDictionaryTKey, TValue(SerializationInfo, StreamingContext)
Initializes a new dictionary instance that contains serialized data.
Top
Properties
Methods
  NameDescription
Public methodCode exampleAdd
Adds an element with the supplied key and value.
Public methodClear
Removes all elements from the dictionary.
Public methodCode exampleContainsKey
Determines whether the dictionary contains the supplied key.
Public methodContainsValue
Determines whether the dictionary contains the supplied value.
Public methodCopyTo
Copies the dictionary to a compatible array, starting at the supplied position.
Public methodElementAt
Gets the key/value pair at the supplied index.
Public methodElementAtOrDefault
Gets the key/value pair at the supplied index or the default if the index is out of range.
Public methodCode exampleElementsBetween
Returns an enumerator that iterates over a range with the supplied bounds.
Public methodElementsBetweenIndexes
Returns an enumerator that iterates over a range with the supplied index bounds.
Public methodElementsFrom
Returns an enumerator that iterates over a range with the supplied lower bound.
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodFirst
Gets the element with the minimum key in the dictionary per the comparer.
Public methodGetEnumerator
Gets an enumerator that iterates thru the dictionary.
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Protected methodGetObjectData
Returns the data needed to serialize the dictionary.
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodIndexOfKey
Gets the index of the element with the supplied key.
Public methodIndexOfValue
Gets the index of the first element with the supplied value.
Public methodLast
Gets the element with the maximum key in the dictionary per the comparer.
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Protected methodOnDeserialization
Implements the deserialization callback and raises the deserialization event when completed.
Public methodRemove
Removes an element with the supplied key from the dictionary.
Public methodRemoveAll
Removes all elements with keys in the supplied collection from the dictionary.
Public methodRemoveAt
Removes an element at the supplied index from the dictionary.
Public methodRemoveRange
Removes an index range of elements from the dictionary.
Public methodRemoveWhere
Removes all elements from the dictionary that match the condition defined by the supplied key-parameterized predicate.
Public methodRemoveWhereElement
Removes all elements from the dictionary that match the condition defined by the supplied key/value-parameterized predicate.
Public methodReverse
Returns an enumerator that iterates thru the dictionary in reverse order.
Public methodCode exampleSkip
Bypasses a supplied number of elements and yields the remaining elements.
Public methodSkipWhile(FuncKeyValuePairTKey, TValue, Boolean)
Bypasses elements as long as a supplied condition is true and yields the remaining elements.
Public methodSkipWhile(FuncKeyValuePairTKey, TValue, Int32, Boolean)
Bypasses elements as long as a supplied index-based condition is true and yields the remaining elements.
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Public methodTryGetGreaterThan
Gets the element with the least key greater than the supplied key.
Public methodTryGetGreaterThanOrEqual
Gets the element with the least key greater than or equal to the supplied key.
Public methodTryGetLessThan
Gets the element with the greatest key less than the supplied key.
Public methodTryGetLessThanOrEqual
Gets the element with the greatest key less than or equal to the supplied key.
Public methodCode exampleTryGetValue
Gets the value associated with the supplied key.
Public methodTryGetValueAndIndex
Gets the value and index associated with the supplied key.
Top
Explicit Interface Implementations
  NameDescription
Explicit interface implementationPrivate methodICollectionKeyValuePairTKey, TValueAdd
Adds an element with the supplied key/value pair.
Explicit interface implementationPrivate methodIDictionaryAdd
Adds the supplied key and value to the dictionary.
Explicit interface implementationPrivate methodICollectionKeyValuePairTKey, TValueContains
Determines if the collection contains the supplied key/value pair.
Explicit interface implementationPrivate methodIDictionaryContains
Determines whether the dictionary contains an element with the supplied key.
Explicit interface implementationPrivate methodICollectionCopyTo
Copies the elements of the collection to an array, starting at the supplied array index.
Explicit interface implementationPrivate methodIEnumerableKeyValuePairTKey, TValueGetEnumerator
Gets an enumerator that iterates thru the dictionary.
Explicit interface implementationPrivate methodIDictionaryGetEnumerator
Gets an enumerator that iterates thru the collection.
Explicit interface implementationPrivate methodIEnumerableGetEnumerator
Gets an enumerator that iterates thru the collection.
Explicit interface implementationPrivate methodISerializableGetObjectData
Returns the data needed to serialize the dictionary.
Explicit interface implementationPrivate propertyIDictionaryIsFixedSize
Indicating that the dictionary is not fixed size.
Explicit interface implementationPrivate propertyICollectionKeyValuePairTKey, TValueIsReadOnly
Indicates that this collection may be modified.
Explicit interface implementationPrivate propertyIDictionaryIsReadOnly
Indicates that the dictionary may be modified.
Explicit interface implementationPrivate propertyICollectionIsSynchronized
Indicates that the collection is not thread safe.
Explicit interface implementationPrivate propertyIDictionaryItem
Gets or sets the value associated with the supplied key.
Explicit interface implementationPrivate propertyIDictionaryTKey, TValueKeys
Gets only the collection of keys from this key/value pair collection.
Explicit interface implementationPrivate propertyIReadOnlyDictionaryTKey, TValueKeys
Explicit interface implementationPrivate propertyIDictionaryKeys
Gets an ICollection containing the keys of the dictionary.
Explicit interface implementationPrivate methodIDeserializationCallbackOnDeserialization
Implements the deserialization callback and raises the deserialization event when completed.
Explicit interface implementationPrivate methodICollectionKeyValuePairTKey, TValueRemove
Removes an element with the supplied key and value from the collection.
Explicit interface implementationPrivate methodIDictionaryRemove
Removes an element with the supplied key from the dictionary.
Explicit interface implementationPrivate propertyICollectionSyncRoot
Gets an object that can be used to synchronize access to the collection.
Explicit interface implementationPrivate propertyIDictionaryTKey, TValueValues
Gets only the collection of values from this key/value pair collection.
Explicit interface implementationPrivate propertyIReadOnlyDictionaryTKey, TValueValues
Explicit interface implementationPrivate propertyIDictionaryValues
Gets an ICollection containing the values of the dictionary.
Top
Remarks

This class emulates and extends SortedDictionaryTKey, TValuewhile significantly improving performance on large collections. Keys must be immutable as long as they are used as keys in the RankedDictionaryTKey, TValueclass. Every key must be distinct and cannot be null, but a value can be for a reference type.

Optimized instance methods with the signatures of LINQ methods have been implemented:

This class also borrows from SortedListTKey, TValuefor indexing functionality:

These properties and methods are inspired by SortedSetT:

Optimized range enumerators are included:

Examples

First is an example of some common operations of this class.

C#
using System;
using System.Collections.Generic;
using Kaos.Collections;

namespace ExampleApp
{
    class RdExample01
    {
        static void Main()
        {
            // Instantiate with four ISO 3166-1 country codes:
            var cc = new RankedDictionary<string,string>
            {
              { "TO", "Tonga" },
              { "DD", "German Democratic Republic" },
              { "CH", "Switzerland" },
              { "RU", "Burundi" }
            };

            // The Add method throws an exception if the new key is
            // already in the dictionary.
            try
            {
                cc.Add ("DD", "East Germany");
            }
            catch (ArgumentException)
            {
                Console.WriteLine ("An element with Key = 'DD' already exists.");
            }

            // The Item property is another name for the indexer,
            // so you can omit its name when accessing elements.
            Console.WriteLine ($"For key = 'CH', value = {cc["CH"]}.");

            // The indexer can be used to change the value associated with a key.
            cc["RU"] = "Russian Federation";

            // The indexer can be used to get a value for a key.
            Console.WriteLine ($"For key = 'RU', value = {cc["RU"]}.");

            // If a key does not exist, setting the indexer for that key
            // adds a new key/value pair.
            cc["SS"] = "South Sudan";

            // The indexer throws an exception if the supplied key is
            // not in the dictionary.
            try
            {
                Console.WriteLine ($"For key = 'ZZ', value = {cc["ZZ"]}.");
            }
            catch (KeyNotFoundException)
            {
                Console.WriteLine ("Key = 'ZZ' is not found.");
            }

            // When a program often has to try keys that are usually not in the
            // dictionary, TryGetValue can be a more efficient way to get values.
            if (cc.TryGetValue ("ZZ", out string value))
                Console.WriteLine ($"For key = 'ZZ', value = {value}.");
            else
                Console.WriteLine ("Key = 'ZZ' is not found.");

            // ContainsKey can be used to test keys before inserting them.
            if (! cc.ContainsKey ("GG"))
            {
                cc.Add ("GG", "Guernsey");
                Console.WriteLine ($"Value added for key = 'GG': {cc["GG"]}");
            }

            // When you use foreach to enumerate dictionary elements,
            // the elements are retrieved as KeyValuePair instances.
            Console.WriteLine();
            foreach (KeyValuePair<string,string> pair in cc)
                Console.WriteLine ($"Key = {pair.Key}, Value = {pair.Value}");

            // To get the values alone, use the Values property.
            RankedDictionary<string,string>.ValueCollection vals = cc.Values;

            // The elements of the ValueCollection are strongly typed
            // with the type that was specified for dictionary values.
            Console.WriteLine();
            foreach(string val in vals)
                Console.WriteLine ($"Value = {val}");

            // To get the keys alone, use the Keys property.
            RankedDictionary<string,string>.KeyCollection keys = cc.Keys;

            // The elements of the KeyCollection are strongly typed
            // with the type that was specified for dictionary keys.
            Console.WriteLine();
            foreach (string key in keys)
                Console.WriteLine ($"Key = {key}");

            // Use the Remove method to remove a key/value pair.
            Console.WriteLine ("\nRemoving 'DD'.");
            cc.Remove ("DD");

            Console.WriteLine ("\nChecking if 'DD' exists:");
            if (! cc.ContainsKey ("DD"))
                Console.WriteLine ("  Key 'DD' not found.");
        }

        /* Output:

        An element with Key = 'DD' already exists.
        For key = 'CH', value = Switzerland.
        For key = 'RU', value = Russian Federation.
        Key = 'ZZ' is not found.
        Key = 'ZZ' is not found.
        Value added for key = 'GG': Guernsey

        Key = CH, Value = Switzerland
        Key = DD, Value = German Democratic Republic
        Key = GG, Value = Guernsey
        Key = RU, Value = Russian Federation
        Key = SS, Value = South Sudan
        Key = TO, Value = Tonga

        Value = Switzerland
        Value = German Democratic Republic
        Value = Guernsey
        Value = Russian Federation
        Value = South Sudan
        Value = Tonga

        Key = CH
        Key = DD
        Key = GG
        Key = RU
        Key = SS
        Key = TO

        Removing 'DD'.

        Checking if 'DD' exists:
          Key 'DD' not found.

        */
    }
}

Next is an example showing binary serialization round tripped.

Note: Serialization is not supported in .NET Standard 1.0.

C#
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Kaos.Collections;

namespace ExampleApp
{
    [Serializable]
    public class PersonComparer : Comparer<Person>
    {
        public override int Compare (Person x, Person y)
        { return x==null? (y==null? 0 : -1) : (y==null? 1 : String.Compare (x.ToString(), y.ToString())); }
    }

    [Serializable]
    public class Person : ISerializable
    {
        public string First { get; private set; }
        public string Last { get; private set; }

        public Person (string first, string last)
        { this.First = first; this.Last = last; }

        protected Person (SerializationInfo info, StreamingContext context)
        {
            this.First = (string) info.GetValue ("First", typeof (String));
            this.Last = (string) info.GetValue ("Last", typeof (String));
        }

        public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
        {
            info.AddValue ("First", First, typeof (String));
            info.AddValue ("Last", Last, typeof (String));
        }

        public override string ToString() => Last + ", " + First;
    }


    class RdExample05
    {
        static void Main()
        {
            IFormatter formatter = new BinaryFormatter();
            var set1 = new RankedDictionary<Person,string> (new PersonComparer());

            set1.Add (new Person ("Hugh", "Mann"), "B+");
            set1.Add (new Person ("Hammond", "Egger"), "C-");

            SerializePersons ("Persons.bin", set1, formatter);
            Console.WriteLine ($"Wrote {set1.Count} key/value pairs.");
            Console.WriteLine ();

            RankedDictionary<Person,string> set2 = DeserializePersons ("Persons.bin", formatter);
            Console.WriteLine ("Read back:");

            foreach (var kv in set2)
                Console.WriteLine (kv);
        }

        public static void SerializePersons (string fn, RankedDictionary<Person,string> set, IFormatter formatter)
        {
            using (var fs = new FileStream (fn, FileMode.Create))
            { formatter.Serialize (fs, set); }
        }

        static RankedDictionary<Person,string> DeserializePersons (string fn, IFormatter formatter)
        {
            using (var fs = new FileStream (fn, FileMode.Open))
            { return (RankedDictionary<Person,string>) formatter.Deserialize (fs); }
        }

        /* Output:

        Wrote 2 key/value pairs.

        Read back:
        [Egger, Hammond, C-]
        [Mann, Hugh, B+]

        */
    }
}
See Also