Looping through object array, possible to get an iterator to index into the object array?
90 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
SoderlingPotro
el 25 de Sept. de 2022
Respondida: Shadow
el 3 de Abr. de 2024
When looping through object arrays using the 'ranged base for loop', is there any way to get an 'iterator' without having to specifically make one elsewhere such that I can index into the object array? What I would like to do is:
for tmpObject = myObjectArray
if ...
myObjectArray(tmpObject) = []
end
end
but this produces the error (which makes sense as tmpObject is not an number)
Unable to use a value of type tmpObject as an index.
I've done this which works, but it just feels messy and seems to defeat the purpose of using the range based for loop:
i = 1;
for tmpObject = myObjectArray
if ...
myObjectArray(i) = []
end
i=i+1;
end
Thanks
1 comentario
Stephen23
el 25 de Sept. de 2022
While MATLAB allows you to iterate over any array type, in practice (as soon as you do anything more complex than just looking at each single element) it is almost always simpler and clearer to iterate over indices into that array.
Respuesta aceptada
dpb
el 25 de Sept. de 2022
Editada: dpb
el 26 de Sept. de 2022
"The MATLAB way" would be to write
isConditon=(EvaluateLogicalExpressionOverTheRange);
myObjectArray(isCondition)=[];
or the construct to save only the ones that aren't empty...
isConditon=(EvaluateLogicalExpressionOverTheRange);
myObjectArray=myObjectArray(~isCondition);
The obvious way to write the above looping construct is that it isn't a fitting place to use the range-based construct -- "if it doesn't fit..."
Avoid the ugly constructs by using something like
for i = 1:numel(myObjectArray):-1:1
if ...
myObjectArray(i) = [];
end
...
end
NB: As @Stephen23 points out, when deleting elements from an array, since numbering of those elements is sequential and begins with numero uno and goes up, to ensure correctness in the operation, one must operate from the top down. That's yet another reason the range-based loop structure isn't appropriate in this application.
3 comentarios
dpb
el 25 de Sept. de 2022
@Stephen23 -- that's good point I forgot to incorporate being only focussed on the fact that the loop isn't the right way here, anyway, probably.
I'll update the Answer to incorporate...
Más respuestas (2)
Walter Roberson
el 25 de Sept. de 2022
When you "for" name=array then matlab iterates over the columns of the array, setting the variable to each column in turn. So tmpObject is already the result of indexing your object array. And then you are trying to use that result to index your object array.
Imagine for example that the object array was a row vector of three figure handles, figure 1, 2, and then 1 again. The for loop would assign one of the figure handles to the variable, and then you would try to index the vector of figure handles by a figure handle. And you would want to do so in a way that even though the first and third entry refer to the same figure and so the same content would be assigned, you would want want different locations to be referred to when used as an index.
Would it be possible to define an object class in such a way that the result of the implicit indexing for for loop purposes was something that you could use the properties of, but could also use the value as an index into the array? I would not rule out the possibility if you define subsref carefully. In particular if you define subsref to return an object that has some kind of unique key for each element, and you define subsasgn to be able to use such objects to match the key to location... ummm I just realized that I am unclear on how deletion works internally. The work flow you are using just might be possible with sufficient coding.
... but using integer indices is a lot simpler.
Shadow
el 3 de Abr. de 2024
Not for deleting stuff inside the array but it provides an index:
enumer = @(my_array) cell2mat(arrayfun(@(x,idx) struct("cargo",x,"idx",idx), my_array(:).', 1:numel(my_array(:).'),UniformOutput=false));
data = string(('A':'F').')
for elem = enumer(data)
disp("Element " + string(elem.cargo) + " with index " + string(elem.idx))
end
0 comentarios
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!