0

As an example, I have a type like this:

public class Stuff
{
    public Double StuffAmount;
    public String StuffDescription;
    public DateTime StuffDate;
}

I need to check for things like standard deviation, and I've found those solutions elsewhere on stackoverflow. But to do them the way they're being proposed, I would need to do something like this:

List<Double> stuffAmounts = new List<Double>();

foreach (var s in List<Stuff>)
{ 
    stuffAmounts.Add(s.StuffAmount); 
}

//now I have a list of doubles that I can do frequently referenced math functions with

Is there anyway to do something like this without having to make a new list, just using my complex type that already has the doubles as properties?

Community
  • 1
  • 1
Eric
  • 2,093
  • 1
  • 27
  • 43
  • 2
    You can `Select` an enumerable of the relevant property from an enumerable of `Stuff`s. Specifically: `var stuffAmounts = myListOfStuff.Select(s => s.StuffAmount);` – Asad Saeeduddin Dec 19 '14 at 00:02
  • Just to add to @Asad's helpful comment, you can also do `List stuffAmounts = myListOfStuff.Select(s => s.StuffAmount).ToList();` in order to put the values into a `List` (as opposed to an `IEnumerable`, which `.Select` returns by default). – danludwig Dec 19 '14 at 00:22

2 Answers2

2

You can do some of the following

Solution 1

As discussed you can just Select into the appropriate type and pass it to your StandardDeviation method

Given

public static double StandardDeviation(List<double> valueList)
{
    double M = 0.0;
    double S = 0.0;
    int k = 1;
    foreach (double value in valueList) 
    {
        double tmpM = M;
        M += (value - tmpM) / k;
        S += (value - tmpM) * (value - M);
        k++;
    }
    return Math.Sqrt(S / (k-2));
}

Usage

List<Double> stuffAmounts = myListOfStuff.Select(s => s.StuffAmount).ToList()
double result = StandardDeviation(stuffAmounts);

Solution 2

Or you could create an extension method and put your standard math calculations in the one place

Given

public static class MathExtensions
{
   public static double StandardDeviation<T>(this List<T> list, Func<T, Double> selector) where T : class
   {
      var m = 0.0;
      var s = 0.0;
      var k = 1;
      foreach (var value in list.Select(selector))
      {
         var tmpM = m;
         m += (value - tmpM) / k;
         s += (value - tmpM) * (value - m);
         k++;
      }
      return Math.Sqrt(s / (k - 2));
   }
}

Usage

var stuffs = new List<Stuff>();
var result = stuffs.StandardDeviation(x => x.StuffAmount);
TheGeneral
  • 69,477
  • 8
  • 65
  • 107
1

From your question I'm not 100% certain this is what you want but it seems to me all you want is to not create a second list and to do this you just need to pass the original list as a parameter and access the appropriate property where you want. Something like the below

Given

public static double StandardDeviation(List<Stuff> valueList)
    {
        double M = 0.0;
        double S = 0.0;
        int k = 1;
        foreach (var value in valueList)
        {
            double tmpM = M;
            M += (value.StuffAmount - tmpM) / k;
            S += (value.StuffAmount - tmpM) * (value.StuffAmount - M);
            k++;
        }
        return Math.Sqrt(S / (k - 2));
    }

Usage

double stdDev = StandardDeviation(data)
kmcc049
  • 2,773
  • 14
  • 13