如何使struct组件成为变量?

时间:2018-02-18 15:39:31

标签: c# list

不确定我是否正确,或者这甚至可能。 我想解释一下我的问题,最好在相关位置的代码中询问,所以请在下面的代码段中查看我的评论。

我想知道如何在不为每个I迭代构建新的值列表的情况下实现此目的。我认为这不是必要的。

这个循环的大局是将3D点的各个维度绘制成三个新的二维图。希望这是有道理的。

for (int i = 0; i < 3; i++) // 3 iterations (X,Y;Z)
{           
    // what here? how to make the data component of Vector3D a variable
    for (int k = 0; k <= Points.Count - 1; k++)
    {
        Vector2D TL = new Vector2D();

        TL.x = ((1 / (float)FrameCount.Sum()) * k);
        TL.y = Points[k].x;      // on i = 0 want Points[k].x
                                 // on i = 1 want Points[k].y
                                 // on i = 2 want Points[k].z

        TimelinePoints.Add(TL); // just collect to a flat list for now
    }
}

3 个答案:

答案 0 :(得分:4)

一种选择是拥有一组可以应用于点的提取函数。然后,您可以使用接受Select的LINQ Func<TInput, int, TOutput>重载来生成要添加的值序列,并以此方式将其添加到TimeLinePoints

// Possibly store this in a static variable somewhere
var extractors = new Func<Point, float>[] { p => p.x, p => p.y, p => p.z };

// Just do this once; store the result as a float for simplicity when dividing later.
float frameSum = FrameCount.Sum();
foreach (var extractor in extractors)
{
    TimeLinePoints.AddRange(Points.Select((point, index) =>
        new Vector2D(index / frameSum, extractor(point));
}

(您可以使用SelectMany潜在地进一步,但那是我开始的地方......)

答案 1 :(得分:4)

与Jon Skeet的答案相比,一个相当多的行人方法是修改Point结构以包含索引器,假设这是一个选项:

public struct Point
{
  float x;
  float y;
  float z;

  public float this[int index]
  {
    get
    {
      switch (index)
      {
        case 0:
        return x;
        case 1:
        return y;
        case 2:
        return z;
        default:
        throw new IndexOutOfRangeException();
      }
    }
    set
    {
      switch (index)
      {
        case 0:
        x = value;
        break;
        case 1:
        y = value;
        break;
        case 2:
        z = value;
        break;
        default:
        throw new IndexOutOfRangeException();
      }
    }
  }
}

然后你可以根据循环计数器的值分配适当的字段,如下所示:

for (int k = 0; k < Points.Count; k++)
{
    Vector2D TL = new Vector2D();

    TL.x = ((1 / (float)FrameCount.Sum()) * k);
    TL.y = Points[k][i];

    TimelinePoints.Add(TL); // just collect to a flat list for now
}

答案 2 :(得分:3)

另一种方法是使用Linq存档:

Points
    //foreach point create 3 Vector2D with X, Y and Z coordinate
    .SelectMany((p, index) => new []
    { 
        new Vector2D(index / frameSum, p.X), 
        new Vector2D(index / frameSum, p.Y), 
        new Vector2D(index / frameSum, p.Z) 
    })
    //unfurl IEnumerable<IEnumerable<Vector2D>> to IEnumerable<Vector2D>
    .Select(v => v) 
    .ToList();