如何进行循环排序和更新列表<>根据具体情况而定

时间:2013-08-08 01:36:24

标签: c# linq list 3d

我在列表中有一个3D数据列表,即c_Top

c_Top列表由一个模式组成,它按y降序排列y值,如下所示:

//[ x,  y, z]      
  [ 2, 10, 1] //c_Top[0]
  [ 7,  8, 1] //c_Top[1]
  [ 1,  7, 2] //c_Top[2]
  [ 3,  6, 1] //c_Top[3]
  [ 4,  6, 2] //c_Top[4]
  .               .   
  .               . 
  .           //c_Top[cTop.Count - 1]

现在,我的目标是根据具有相同z值的条件获取c_Top列表中的所有x值

for (int i = 0; i < c_Top.Count; i++)
{
    if (i != c_Top.Count - 1)
    {
        // if the next data and the current data has same z, then proceed
        if (c_Top[i].p.Z == c_Top[i + 1].p.Z)
        {
            // if the x of next data is greater than current x of current data
            if (c_Top[i + 1].p.X > c_Top[i].p.X)
            {
                // Select all the x and y value at X+ direction
                xy_xplusList = c_Top.Select(x => x.p.X).OrderBy(x => x).ToList();
            }

            // if the x of next data is smaller than current x of current data
            else if (c_Top[i + 1].p.X < c_Top[i].p.X)
            {
                // Select all the x and y value at X- direction
                xy_xminusList = c_Top.Select(x => x.p.X).OrderByDescending(x => x).ToList();
            }
        }

        if (xy_xplusList.Count > 0)
        {
              //Do something
        }

        if (xy_xminusList.Count > 0)
        {
              //Do something
        }
}

我正在使用上面的for循环,以及上面的数据示例。由于c_Top[1]c_Top[2]具有不同z值的原因。因此,当i = 1the c_Top[1].p.X未保存时,即使它与c_Top[0]

中的z相同

我得到了这样的结果

//Output
xy_xplusList  =  { 2 } //only one x values from  c_Top[0] is saved
xy_xminusList =  { 0 }

但实际上我想要的结果是这样的

c_Top[0] // Output xy_xplusList = { 2, 3 } 
         //       xy_xminusList = { 0 }

c_Top[1] // Output xy_xplusList = { 0 }
         //       xy_xminusList = { 3 }

c_Top[2] // Output xy_xplusList  = { 1 , 4 }
         //        xy_xminusList = { 0 }

c_Top[3] // Ouput xy_xplusList  = { 7 }
         //       xy_xminusList = { 2 }

c_Top[4] // Ouput xy_xplusList  = { 0 }
         //       xy_xminusList = { 1 }

简而言之。我想考虑c_Top列表中的每个数据。

考虑c_Top[i]时:

如果c_Top列表中z值的所有数据与c_Top[i].p.Z具有相同的z,则它将检查c_Top列表中的所有x值。

如果x值大于c_Top[i].p.X,那么x将被添加到xy_xplusList

如果x值小于c_Top[i].p.X,那么x将被添加到xy_minusList

有没有LINQ方式呢?

在我使用相同的z排序之后,检查列表中的所有x,然后添加到xy_xplusList

说明更新

在列表中的每个坐标中,首先我检查它们是否在同一个Z字段中。如果它们是相同的Z字段,那么我检查所有的X。

如果X大于当前x坐标,则将x添加到xplusList

如果X小于当前x坐标,则将x添加到xminusList

*我对列表中的所有坐标重复上述过程。

解释Update2

enter image description here enter image description here 成像上面的金字塔多边形的尖端是c_Top列表中的一个坐标

要绘制金字塔多边形,我们需要TIP的坐标,尖端的RHS坐标和尖端的LHS坐标,FRONT的坐标以及背面的坐标。

所以,现在,回到这个问题。我在c_Top列表中存储了多个TIP坐标。现在我想从尖端(在+ X方向)检查RHS中的所有坐标,并从尖端(在-X方向)检查LHS中的所有坐标。对于FRONT和BACK坐标也一样。

我有多个TIP坐标的成像排列在不同高度的同一Z字段中。我想将所有尖端连接到最高尖端坐标,如下面的粉红色线所示: enter image description here

更新:自己回答问题,此问题将被关闭

//Group all the Z coordinate throughout the v_Tip list
var groupedZ = from p in v_Tip
               group p by p.p.Z into q
               select q;

foreach (var groupZ in groupedZ)
{
    //Order the groupZ with Y coordinate descending order
    var SameZList = groupZ.OrderByDescending(y => y.p.Y).ThenBy(x => x.p.X).ToList();

    //Since the list is order by descending w.r.t Y coordinate, the SameZList[0] will be the peak coordinate in groupZ
    var peakZ = SameZList[0];

    // At same Z, mean at XY plane
    for (int i = 1; i < SameZList.Count; i++)
    {
        // mean the x is at the RHS from the peak
        if (peakZ.p.X < SameZList[i].p.X)
        {
            // add all the X and Y coordinates in RHS direction from the peak (X+ direction from the peak
            xy_xplusList.Add(SameZList[i].p.X);
            xy_yplusList.Add(SameZList[i].p.Y);
        }
        else // the x is at the LHS from the peak
        {
            // add all the X and Y coordinates in LHS direction from the peak (X- direction from the peak
            xy_xminusList.Add(SameZList[i].p.X);
            xy_yminusList.Add(SameZList[i].p.Y);
        }
    }

}

2 个答案:

答案 0 :(得分:1)

我不确定我是100%在你的问题上...但这对你有用吗?

    public void DoWork(List<int[]> c_Top)
    {
        var distinctZvalues = c_Top.Select(p => p[2]); // this gets an enumerable object of unique Z values

        List<int[]> xy_minus = new List<int[]>();
        List<int[]> xy_plus = new List<int[]>();

        foreach (var z in distinctZvalues)
        {
            List<int[]> coords = c_Top.Where(p => p[2] == z).ToList(); // pull all int[] from c_Top where z == z
            foreach (int[] coord in coords)
                if (coord[0] > coord[1])
                    xy_minus.Add(coord);
                else
                    xy_plus.Add(coord);
        }
    }

或者,经过进一步审核,您可能正在寻找基于Z值的唯一列表......

public void DoWork2(List<int[]> c_Top)
    {
        var distinctZvalues = c_Top.Select(p => p[2]); // this gets an enumerable object of unique Z values

        Dictionary<int, List<int[]>> xy_minus = new Dictionary<int, List<int[]>>();
        Dictionary<int, List<int[]>> xy_plus = new Dictionary<int, List<int[]>>();

        foreach (var z in distinctZvalues)
        {
            List<int[]> minus = new List<int[]>();
            List<int[]> plus = new List<int[]>();
            List<int[]> coords = c_Top.Where(p => p[2] == z).ToList(); // pull all int[] from c_Top where z == z
            foreach (int[] coord in coords)
                if (coord[0] > coord[1])
                    minus.Add(coord);
                else
                    plus.Add(coord);
            xy_minus.Add(z, minus);
            xy_plus.Add(z, plus);
        }
    }

答案 1 :(得分:0)

如果我没有误解你的问题

 class Program
{
    static void Main(string[] args)
    {
        List<int[]> c_top=new List<int[]>();
        c_top.Add(new int[3]{ 2, 10, 1});
        c_top.Add(new int[3]{ 7,  8, 1});
        c_top.Add(new int[3]{ 2,  7, 2});
        c_top.Add(new int[3]{ 3,  6, 1});
        c_top.Add(new int[3]{  4,  6, 2});

        var result=c_top.Where(x => x[0] == x[2]).Select(s => s[0]).ToList();
    }
}