0

I have a class:

 namespace XMLParserAverage11
 {
     public class cPoint
     {
        public string point;
        public string time;
        public double xPoint;
        public double yPoint;
        public double StdDevX;
        public double StdDevY;
        public string csv;

       public cPoint(string n, double x, double y)
       {
           this.point = n;
           xPoint = x;
           yPoint = y;
       }

 }
}

This is used to store information obtained from reading an XML file and then it is put into

List<cPoint> Sorted

What I would like to do is store the "xPoint" into an array and the "yPoint" into another array for all "point" that has the same value. This is so I can ultimately use Statistics.PopulationStandardDeviation()from Mathnet.Numerics NuGet package which requires a double array and calculate the total standard deviation of xPoint and yPoint per same "point" in List Sorted.

if (measurementType == "Body")
{
    double a = Convert.ToDouble(xOffset);
    double b = Convert.ToDouble(yOffset);
    cPoint Point = new cPoint(location, a, b);
    Point.time = endTime;
    //  Point.point = location;
    //   Point.xPoint = Convert.ToDouble(xOffset);
    //    Point.yPoint = Convert.ToDouble(yOffset);
    sorted.Sort((x, y) => x.point.CompareTo(y.point));
    //   double[] balanceX = {Point.xPoint};
    //  double[] balanceY = {Point.yPoint};
    if (sixSig == true)
    {
        List<cPoint> pointList = new List<cPoint>();
        // Select all the distinct names
        List<string> pointNames = location.Select(x => xOffset).Distinct().ToList();

        foreach (var name in pointNames)
        {

            // Get all Values Where the name is equal to the name in List; Select all xPoint Values
            double[] x_array = pointList.Where(n => n.point == name).Select(x => x.xPoint).ToArray();
            Point.StdDevX = Statistics.StandardDeviation(x_array);

            // Get all Values Where the name is equal to the name in List; Select all yPoint Values
            double[] y_array = pointList.Where(n => n.point == name).Select(x => x.yPoint).ToArray();
            Point.StdDevY = Statistics.StandardDeviation(y_array);
        }

        csvString = Point.time + "," + Point.point + "," + Point.xPoint + "," + Point.yPoint + "," + Point.StdDevX + "," + Point.StdDevY;
        Point.csv = csvString;
        sorted.Add(Point);

    }
    else
    {
        csvString = endTime + "," + location + "," + xOffset + "," + yOffset;
        Point.csv = csvString;
        sorted.Add(Point);
    }
}

My output will eventually resemble this.
Obviously I'm a beginner so any help would be greatly appreciated.

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
ChrisD91
  • 249
  • 3
  • 10
  • Your code is a little confusing.where is `sorted` populated? , in the last line? Do you calculate the `PopulationStandardDeviation` with only 1 value? why do you expect in the foreach loop two different outcomes for `a` and `b` if you use the same single value from `balanceX` ? – Mong Zhu Aug 18 '16 at 10:39
  • this sounds like an XY problem – Neil Aug 18 '16 at 10:45
  • @Mong Zhu there's about 500 extra lines of code that I didn't want to post but `sorted` is initialised as a `cPoint` list in another class. Everything is stored initially in `cPoint Point` then added to `sorted` when all the calculations etc. are done. – ChrisD91 Aug 18 '16 at 10:58

1 Answers1

1

EDIT:

ok Here is a small Console application which illustrates the procedure that you are looking for I think. I cut down (and renamed) your class cPoint for this purpose:

public class C_Point
{
    public string point;
    public double xPoint;
    public double yPoint;

    public C_Point(string n, double x, double y)
    {
        this.point = n;
        xPoint = x;
        yPoint = y;
    }
}

class Program
{


    static void Main(string[] args)
    {
        List<C_Point> pointList = new List<C_Point>();

        pointList.Add(new C_Point("P1", 1, 11));
        pointList.Add(new C_Point("P1", 2, 22));
        pointList.Add(new C_Point("P1", 3, 33));
        pointList.Add(new C_Point("P10", 101, 111));
        pointList.Add(new C_Point("P10", 201, 211));
        pointList.Add(new C_Point("P10", 301, 311));

        // Select all the distinct names
        List<string> pointNames = pointList.Select(x => x.point).Distinct().ToList();

        foreach (var name in pointNames)
        {
            Console.WriteLine("Name: {0}", name);

            // Get all Values Where the name is equal to the name in List; Select all xPoint Values
            double[] x_array = pointList.Where(n => n.point == name).Select(x => x.xPoint).ToArray();

            Console.WriteLine(String.Join(" ", x_array));

            // Get all Values Where the name is equal to the name in List; Select all yPoint Values
            double[] y_array = pointList.Where(n => n.point == name).Select(x => x.yPoint).ToArray();

            Console.WriteLine(String.Join(" ", y_array));
        }
        Console.ReadKey();
    }
}

You can just copy paste it in a console project and let it run. It will display the array values with the name of the point, in your case the Location. Did I got closer to your Problem?

EDIT 2:

when you try to get all the distinct names of your points you need to extract them from the List where all the points are.

Here you try to select something from a string as it seems. This will not work.

// Select all the distinct names
List<string> pointNames = location.Select(x => xOffset).Distinct().ToList();

Instead use the sorted List. I think you have them all in there, don't you? Select(x=>x.point) means: the x is a placeholder for any element (in your case of type cPoint) inside your list. after the => you specify which property of the elements should be selected! in this case x.point. The result will be a list of all the values of this property of all elements. The Distinct call gets rid of the multiple entries.

This: (x => xOffset) does not work because it is not a valid expression and because you have no property Offset that could be selected in your class cPoint

This will not work either:

double[] x_array = pointList.Where(n => n.point == name).Select(x => x.xPoint).ToArray();

because your pointList is empty! You need to use again the List with all your points!

Hope this helps you further. Write me if not.

For more information please read more about Lambda expressions

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
  • `sorted` is a bunch of data that I have read from an XML file. All of the `xPoint` and `yPoint` values will always be unique but `point` will not. The code should create a `double[] x_array` and `double[] y_array` for each new 'point' in 'sorted' or just add to the existing array if `point` is already contained somewhere in `sorted`. Hopefully this clears some of the confusion up? Thanks for the help – ChrisD91 Aug 18 '16 at 14:39
  • I've updated my original question with an image showing what my eventual output will be. Hopefully this will clarify things. – ChrisD91 Aug 18 '16 at 14:47
  • @ChristopherDyer ok I think I understood you a little better. I edited my answer. Have a look – Mong Zhu Aug 18 '16 at 15:55
  • Firstly, my apologies for such a late response, I was taken off this project for two weeks. This is exactly what I want. Can you give some guidance to integrating your code within my project to the point where I am storing the x and y values in the double arrays? I'm struggling with modifying your code for my purpose as this is my first c# project. Thank you. – ChrisD91 Aug 30 '16 at 08:12
  • @ChristopherDyer I have updated my answer, have a look – Mong Zhu Aug 30 '16 at 12:24
  • @ChristopherDyer glad I could help – Mong Zhu Aug 31 '16 at 06:15