Reputation: 27
I do this multiple times every frame in my game. So looking for a way not to loop multiple times. Thanks for taking a look :)
List<Vector3> listVectors = new List<Vector3>();
for (int i = 0; i < 2000; i++) {
listVectors.Add(new Vector3(i,i,i));
}
var listX = from v in listVectors select v.x;
var listY = from v in listVectors select v.y;
var listZ = from v in listVectors select v.z;
// Is it possible to create this without looping multiple times
List<IEnumerable<float>> listV = new List<IEnumerable<float>>{listX,listY,listZ};
Upvotes: 1
Views: 1763
Reputation: 120518
List<List<float>> lists = listVectors
.SelectMany(v => new[]{
new{k = 'x', v = v.x},
new{k = 'y', v = v.y},
new{k = 'z', v = v.z}})
.GroupBy(x => x.k)
.OrderBy(g => g.Key)
.Select(g => g.Select(x => x.v).ToList())
.ToList();
Upvotes: 2
Reputation: 727027
Since you are producing three different results, you would need to write a loop yourself:
List<float> listX = new List<float>(listVectors.Count);
List<float> listY = new List<float>(listVectors.Count);
List<float> listZ = new List<float>(listVectors.Count);
foreach (var vec in listVectors) {
listX.Add(vec.x);
listY.Add(vec.y);
listZ.Add(vec.z);
}
You could potentially do that with List<T>.ForEach
with side effects, but that would be the same thing:
listVectors.ForEach(vec => {
listX.Add(vec.x);
listY.Add(vec.y);
listZ.Add(vec.z);
});
Of course the best thing would be to avoid copying altogether. You could do it with a simple trick that passes a list of Vector3
objects along with the "extraction" functor, like this: instead of
void Process(IList<float> data) {
foreach (float f in data) {
// Do something with f
}
}
and calling it
Process(listX);
you write
void Process(IList<Vector3> data, Func<Vector3,float> extract) {
foreach (Vector3 v in data) {
float f = extract(v);
// Do something with f
}
}
and call
Process(listVectors, v => v.x);
Upvotes: 1