Unitize vectors in lists

grasshopper

#1

There is probably some obvious reason I’m missing but why can’t I unitize all the vectors in a list using a foreach or a for loop using this syntax?

foreach (Vector3d v in V)
{
v.Unitize();
}

for (int i = 0; i < V.Count; i++)
{
V[i].Unitize();
}

or in an Array

for(var l = 0; l < vectors.Length; l++)
{
vectors[l].Unitize();
}


(Vicente Soler) #2

When you do a foreach loop, the current item (v) will be a copy of the object in the list. If it’s a class, you can modify it since the copy is a reference to the actual object. When it’s a struct, like a Vector3d, modifying that copy will not change the object inside the list. When retrieving items inside a List collection, same thing, it returns a copy of the object inside the list.

You could do something like:
var normalized = V. Select(v=> {v.Unitize(); return v;});


#3

Thank you for your clear explanation, my knowledge of C# is not very wide. If I understand correctly the alternative syntax you propose is LINQ. The Select() method runs a foreach loop assigning to each v in V a new value which then you add to a new list. What I don’t get is the curly brackets part, because the Select method syntax on MSDN site is Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>). Is this like the curly brackets part of a foreach loop, where you would have two statements separated by ; ? Thanks again


(Vicente Soler) #4

The Func delegate can be returned as a lambda. Usually you would use an expression lambda, but you can enclose several lines in brackets for a statement lambda. See the documentation:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions

Alternatively you can use a for loop where you assign the copied item back to the list after modifying it:

for(int i=0;i<V. Count;i++)
{
var v = V[i];
v. Unitize();
V[i] = v;
}


(Vicente Soler) #5

Arrays on the other hand don’t return a copy when accessing an item, so your third example should work.


#6

Yes, before your reply I was using something similar but using another list:
for (int i = 0; i < V.Count; i++)
{
Vector3d v1 = new Vector3d(V[i]);
v1.Unitize();
vectors.Add(v1);
}

At the time I probably did some mistake but your reply I got back to it and it indeed works. Thanks for the link.