ChrisD91
ChrisD91

Reputation: 261

Finding changes in a list then storing specific values into an array C#

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.

Upvotes: 0

Views: 146

Answers (1)

Mong Zhu
Mong Zhu

Reputation: 23732

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

Upvotes: 1

Related Questions