Looping through object array, possible to get an iterator to index into the object array?
90 次查看(过去 30 天)
显示 更早的评论
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 个评论
Stephen23
2022-9-25
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.
采纳的回答
dpb
2022-9-25
编辑:dpb
2022-9-26
"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 个评论
dpb
2022-9-25
@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...
更多回答(2 个)
Walter Roberson
2022-9-25
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
2024-4-3
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 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!