Divide list of points into lists based on X-coordinate

I am very new to C# so bear with me. I am writing a C# script inside rhino grasshopper, where I have created a list of points based off the same colored pixels of an image. I am wondering if there is any way to sort and split the list into more lists based on the x or y coordinate of the points? For example, all points with the same X-coordinate will be sorted into one list, so there will be a list of rows of the points. I know how to do this in grasshopper by the member index component, but I have no idea of how to do it in C#.

So in the code below, I am trying to split the List sitePx into more lists based on the points’ X-coordinate, the output will be a branched structure rather than a flat one.

public List SitePt(string imgPath, Color myColor)
{
Bitmap siteImg = new Bitmap(imgPath);
List sitePx = new List();

  for (int i = 0; i < siteImg.Width; i++)
  {
    for (int j = 0; j < siteImg.Height; j++)
    {
      Color c = siteImg.GetPixel(i, j);
      if(myColor.Equals(c))
      {
        Point3d p = new Point3d(i, j, 0);
        sitePx.Add(p);
      }
    }
  }
  return sitePx;

}

Hello.

If you want to separate points by X coordinate, how about GroupBy in Linq?
GroupBy.gh (7.1 KB)

public List<List<Point3d>> SortSitePx(List<Point3d> sitePx)
{
  // Create a new list to store the sorted points
  List<List<Point3d>> sortedPx = new List<List<Point3d>>();

  // Loop through the list of points
  foreach (Point3d p in sitePx)
  {
    // Create a new list to store the points with the same x-coordinate
    List<Point3d> xRow = new List<Point3d>();

    // Loop through the list again to find the points with the same x-coordinate
    foreach (Point3d p2 in sitePx)
    {
      // Add the points with the same x-coordinate to the list
      if (p.X == p2.X)
      {
        xRow.Add(p2);
      }
    }

    // Add the list of points with the same x-coordinate to the sorted list
    sortedPx.Add(xRow);
  }

  return sortedPx;
}

To split the list of points into separate lists based on the X-coordinate, you could create a dictionary where the keys are the X-coordinate values and the values are lists of points. Then, you can iterate through the points in sitePx and add them to the appropriate list in the dictionary based on their X-coordinate.

Dictionary<int, List<Point3d>> sitePxDict = new Dictionary<int, List<Point3d>>();

foreach (Point3d p in sitePx)
{
  int x = (int)p.X;
  if (!sitePxDict.ContainsKey(x))
  {
    sitePxDict[x] = new List<Point3d>();
  }
  sitePxDict[x].Add(p);
}

After running this code, the dictionary sitePxDict will contain a separate list of points for each unique X-coordinate value in sitePx. You can access these lists by using the X-coordinate value as a key in the dictionary. For example, to access the list of points with an X-coordinate of 10, you can use sitePxDict[10].

Dear @Olivia9
in which context do you use this function / search-result / data ?
There is different kinds of collections in c# and additional possibilities in Rhinocommon and Grasshopper API.
one dimensional or multi-dimensional Arrays.
Lists, or Lists of Lists
Dictionary, or a Dictionary containing lists

It really depends on where you use the result of the function.

The member Index component is doing something similar to multiple calls of

(this can also be achieved with linq)
Creating a list of all indices and returns this list and it s length.

Data Tree
Depending on what you re doing - additionally to approaches posted above - you might profit from using datatrees inside your c# component:

this topic also shows a simple example how to create a datatree

hope this helps - kind regards -tom

thank you!

I will look into that, thanks!

That is another way, thanks!

1 Like

Yes this worked, thanks!