Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

which c# collection to use instead of List<KeyValuePair<string, double>>?

I want to store data such as

{
 {"apple",15   }
 {"pear",12.5  }
 {"", 10       }
 {"", 0.45     }
}

Data will be plotted on a bar chart (string will be the legend and double will be the value) Insert order is important. Perfs don't matter. Strings could be duplicated or empty. (values could be duplicated too)

I need to get min and max values (easily if possible) to set the scale.

I use

List<KeyValuePair<string, double>> data = new List<KeyValuePair<string, double>>();
data.Add(new KeyValuePair<string,double>("",i));

Quite boring and unreadable. Is there a cleaner way to do it ?

StringDoubleCollection data = new StringDoubleCollection();
data.add("apple",15);
data.add("",10);

double max = data.values.Max(); 
double min = data.values.Min();

if not how to get the max value of List<KeyValuePair<string, double>> without too much hassle

NameValueCollection looks nice but its a <string,string> I need a <string,double>

like image 508
frenchone Avatar asked Sep 21 '11 17:09

frenchone


2 Answers

You could create a class like the following:

class X
{
     public string Name { get; set; }
     public double Value { get; set; }

     // name is an optional parameter (this means it can be used only in C# 4)
     public X(double value, string name = "")
     {
         this.Name = name;
         this.Value = value;
     }

     // whatever
}

And then get maximum and minimum values using LINQ with a selector:

var data = new List<X>();
data.Add(new X(35.0, "Apple"))
data.Add(new X(50.0));

double max = data.Max(a => a.Value);
double min = data.Min(a => a.Value);

EDIT: if the code above still seems unreadable to you try to improve it using an operator for cases in which you want to have just the value.

// Inside X class...
public static implicit operator X(double d)
{
    return new X(d);
}

// Somewhere else...
data.Add(50.0);
like image 156
as-cii Avatar answered Oct 23 '22 06:10

as-cii


To determine which data structure you really want, lets look at your usage patterns.

  • Insert order matters.
  • You don't access your items by key.
  • You want min and max.

A heap offers min or max, but doesn't preserve order. A hash based dictionary also doesn't preserve order. A List is actually a good choice for your data structure. It is available and offers excellent support.

You can prettify your code by defining classes for both the data structure and your bar data. And you can add min/max functionality to the collection. Note: I didn't use the Linq Min/Max functions, because they return the minimum value, not the minimum element.

public class BarGraphData {
    public string Legend { get; set; }
    public double Value { get; set; }
}

public class BarGraphDataCollection : List<BarGraphData> {
    // add necessary constructors, if any

    public BarGraphData Min() {
        BarGraphData min = null;
        // finds the minmum item
        // prefers the item with the lowest index
        foreach (BarGraphData item in this) {
            if ( min == null )
                min = item;
            else if ( item.Value < min.Value )
                min = item;
        }
        if ( min == null )
            throw new InvalidOperationException("The list is empty.");
        return min;
    }

    public BarGraphData Max() {
        // similar implementation as Min
    }
}
like image 26
Mark Avatar answered Oct 23 '22 07:10

Mark