makerofthings7
makerofthings7

Reputation: 61463

What collection object is appropriate for fixed ordering of values?

Scenario: I am tracking several performance counters and have a CounterDescription[] correlate to DataSnapshot[]... where CounterDescription[n] describes the data loaded within DataSnapshot[n].

I want to expose an easy to use API within C# that will allow for the easy and efficient expansion of the arrays.

Simplified example (it gets more complex)

CounterDescription[0] = Humidity;
DataSnapshot[0] = .9;
CounterDescription[1] = Temp;
DataSnapshot[1] = 63;

Note how my intent is to correlate many Datasnapshots with a DateTime reference, and using the offset of the data to refer to its meaning. This was determined to be the most efficient way to store the data on the back-end, and has now reflected itself into the following structure:

  public class myDataObject { 
    [DataMember]
    public SortedDictionary<DateTime, float[]> Pages { get; set; }

    /// <summary>
    /// An array that identifies what each position in the array is supposed to be
    /// </summary>
    [DataMember]
    public CounterDescription[] Counters { get; set; }
   }

How will myDataObject be used?:

I will frequently search for a counter by string name, and use its' position to determine what offset a particular value will be saved. I can use an homegrown extension method to enumerate the object, or leverage the framework if ordering is guaranteed.

Also, I will need to expand each of these arrays as new sensors are added: (float[] and CounterDescription[] ), but whatever data already exists must stay in that relative offset. I don't want the serialized version of this object to confuse Temp (offset 1) with Humidity (offset 0)

Which .NET objects support this fixed ordering, expansion, and enumeration (and optional searching by string)? My guess is to use one of these objects...

Array[] , LinkedList<t>, and List<t>

Upvotes: 0

Views: 487

Answers (3)

Patrick Szalapski
Patrick Szalapski

Reputation: 9439

Any list (IList) has ordered values. I always assume that mere IEnumerables have no strict order underneath; although they usually do, you can't guarantee it. I agree with the others that a Dictionary (or some other IDictionary) is a good fit.

Upvotes: 0

Allon Guralnek
Allon Guralnek

Reputation: 16121

Use a Dictionary<string, double> so that each name (string) maps to a value (double):

var counters = new Dictionary<string, double>();

counters["Humidity"] = 0.9;
counters["Temp"] = 63;

And use a service that gets and sets the counter values:

[OperationContract]
public double GetCounter(string name)
{
     return Counters[name];
}

[OperationContract]
public void SetCounter(string name, double value)
{
     Counters[name] = value;
}

You can use your CounterDescription and/or DataSnapshot classes in the same way, but make sure that the class you use as the key (probably CounterDescription) overrides Object.Equals() and Object.GetHashCode() with a proper implementation.

Upvotes: 1

Jim Mischel
Jim Mischel

Reputation: 134005

If CounterDescription is a string or an enum, then Dictionary seems like a good fit:

Dictionary<string, double> Counters = new Dictionary<string, double>();
// Then initialize it ...
Counters.Add("Humidity", 0);
Counters.Add("Temp", 0);
// To update:
Counters["Humidity"] = 0.9;
// To query
double humidity = Counters["Humidity"];

You can do the same sort of thing with a enum for the key, rather than a string.

If your CounterDescription type is a complex object, you can still use it as a key, but you'll need to implement IComparable or provide a comparison function.

Upvotes: 0

Related Questions