Changing the values of multiple objects at once?

96 views (last 30 days)
Nathan Bush
Nathan Bush on 12 May 2017
Edited: men8th on 13 Mar 2023
I have an array of objects with certain properties.
Is it possible to change the values of a certain property for all objects in the array at once (without looping through them) ?
我肌萎缩性侧索硬化症o like to be able to change the properties by adding a fixed value to all of them (in other words, performing an operation on a single property for all objects at once). Is this also possible without a for loop?
Apologies if this is very simple.
e.g Below is a simplified version of what I'm trying to achieve
classdeftest < dynamicprops
properties
Value
end
methods
functionemission = is_greater(input,obj)
a = rand;
emission = a < input;
end
end
end
%an array of the object
fori=1:1:10
objarray(i)=test
end
%the below does not work, but shows what I'm trying to do
objarray.Value = rand;
objarray.Value = objarray.Value + 0.6;
1 Comment
men8th
men8th on 30 Oct 2019
Edited:men8th on 13 Mar 2023
Having faffed about with this for a bit now I can confirm that Guillaume's answer is the way to go. The functions deal() and num2cell() are what is needed.
What I have learnt since then though is that assignment using a for loop is actually significantly faster (at least for the cases I've tested using the performance testing framework) than converting to cell arrays and then assigning to cell arrays to the properties of the array of objects.
Finally, if performance is important, it is important to get the data structures right. Better to have a single object with array valued properties than an array of objects with scalar valued properties. In other words, if you are reading this page because you are looking for vectorisation type performance enhancements with object arrays, perhaps you should consider if a single object with array properties and vectorised methods might be better.

Sign in to comment.

Answers (2)

Guillaume
Guillaume on 12 May 2017
Edited:Guillaume on 12 May 2017
You do not need to create a special set function or override any operator to assign values to a property of an array of objects. The syntax is however slightly obscure and awkward as you need to use temporary cell arrays for the values to assign.
%object creation
fori=1:1:10
objarray(i)=test
end
%assigning the same value to each object. Use deal:
[objarray。交易价值]= (0.5);
%assigning different values to each object.
%Convert array of values to cell array, then convert cell array to comma-separated list:
values = num2cell(rand(1, numel(objarray)));
[objarray。Value] = values{:};
%add a constant to each property.
%convert list of values to array. add value. convert array to cell array. convert cell array to comma-separated list:
values = num2cell([objarray.Value] + 0.6);
[objarray。Value] = values{:};
Unfortunately, you can't do the conversion to cell array and the conversion of cell array to comma separated list on the same line due to matlab chaining rules, num2cell(x){:} is a syntax error. So in most cases, you need at least two lines. As I said, it's a bit awkward.
6 Comments
Stephen23
Stephen23 on 7 May 2020
Edited:Stephen23 on 7 May 2020
"but I think this works only for setting all objects properties to the same value?"
No, you missed the distinction that Steven Lord gave:
set(t,'Color','r')% <- all objects use the same value
set(t, {'Color'}, color)% <- every object has its own value
% ^ ^ The cell array is significant!
Change your code to follow the example Steven Lord gave (and as explained in the set documentation):
set(ObHandles,{'Position'},OrigPos);
% ^ ^ you need these!

Sign in to comment.


Adam
Adam on 12 May 2017
Edited:Adam on 12 May 2017
The default set function for properties works on scalar objects only, but you can write your own functions (and any other function you overload or write yourself) to support vectors (or even matrices) of objects which you then act on.
Then your code above should work fine. I don't tend to do this myself except in a few places because it is a lot of effort supporting vectors of objects in all functions, but it can be useful.
You can do this, though it just moves the for loop inside the class:
classdefMyClass < handle
properties
Value
end
methods
functionset.Value( objArray, value )
validateattributes( objArray, {'MyClass'}, {'vector'} )
validateattributes( value, {'numeric'}, {'scalar'} )
fori = 1:numel( objArray )
objArray(i).Value = value;
end
end
end
end
m(4) = MyClass;
m.Value = 7;
It quickly gets messy from a design perspective though because then you start asking yourself 'Should I also support a vector of values so that I can set the value of 10 objects to each value of an array of 10 numbers?'. And the code soon starts to get very complicated.
The plus operator could be similarly overloaded:
functionobjArray = plus( objArray, value )
validateattributes( objArray, {'MyClass'}, {'vector'} )
validateattributes( value, {'numeric'}, {'scalar'} )
fori = 1:numel( objArray )
objArray(i).Value = objArray(i).Value + value;
end
end
or something similar. Again though you have the questions of what you support because the standard + operator supports more than just adding a scalar to an array (as well as being symmetric, but that is another matter entirely).
Section 17-45 of the Matlab OOP bible covers other ways to overload the plus operator with a double operator overload also, but the class needs to be basically a wrapper for one main value property for this to make much sense. Just adding 7 to an arbitrary class full of properties doesn't really have an obvious meaning.
Even the simple early example in 2-6 to 2-7 of that linked document shows how quickly design question can start to arise from relatively simple overloads. In that example a plus operator is overloaded that simply adds the 'Value' or one class to the 'Value' of another. That is fair enough, but the output is a double. Personally I would expect that if I added two of those 'BasicClass' objects together I would end up with a BasicClass object as my output, containing the summed values of the two inputs, rather than just a raw double.
1 Comment
Stephen23
Stephen23 on 12 May 2017
Note that set and get 支持多种图形对象处理金宝app/or multiple values in arrays. As Adam says the syntax gets a bit complex, but it can be done.

Sign in to comment.

Categories

Find more onGraphics Object ProgramminginHelp CenterandFile Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!