3

I need to build an array of objects of class ID using arrayfun:

% ID.m
classdef ID < handle
    properties
        id
    end
    methods
        function obj = ID(id)
            obj.id = id;
        end
    end
end

But get an error:

>> ids = 1:5;
>> s = arrayfun(@(id) ID(id), ids) 
??? Error using ==> arrayfun
ID output type is not currently implemented.

I can build it alternatively in a loop:

s = [];
for k = 1 : length(ids)
    s = cat(1, s, ID(ids(k)));
end

but what is wrong with this usage of arrayfun?

Edit (clarification of the question): The question is not how to workaround the problem (there are several solutions), but why the simple syntax s = arrayfun(@(id) ID(id), ids); doesn't work. Thanks.

3 Answers 3

5

Perhaps the easiest is to use cellfun, or force arrayfun to return a cell array by setting the 'UniformOutput' option. Then you can convert this cell array to an array of obects (same as using cat above).

s = arrayfun(@(x) ID(x), ids, 'UniformOutput', false);
s = [s{:}];
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but it seems as a patch, like the loop method. My question was why arrayfun(@(id) ID(id), ids) doesn't work. Is it a Matlab's bug, or wrong usage?
as I sometimes miss the python functionality to endlessly extend commands, and frequently use your cell to array construction I often declare an anonymous function to do it in one go: dealcell = @(x)x{:};, which can then be used like s = [dealcell(arrayfun(...))];
You need s = reshape(s, size(ids)) to make that truly match arrayfun
3

You are asking arrayfun to do something it isn't built to do.

The output from arrayfun must be:

scalar values (numeric, logical, character, or structure) or cell arrays.

Objects don't count as any of the scalar types, which is why the "workarounds" all involve using a cell array as the output. One thing to try is using cell2mat to convert the output to your desired form; it can be done in one line. (I haven't tested it though.)

s = cell2mat(arrayfun(@(id) ID(id), ids,'UniformOutput',false));

3 Comments

actually CELL2MAT will fail with the error Cannot support cell arrays containing cell arrays or objects.
@Amro Ah, interesting. Thanks for pointing that out, like I said I hadn't tested it. Is there a way to get handles to the objects into a vector?
you can create object arrays (I posted an answer), just not with ARRAYFUN. In fact ARRAYFUN can iterate over array of objects (as input), just not return them as output (must return scalars of cells as you pointed out). You can also do it as @robince showed
2

This is how I would create an array of objects:

s = ID.empty(0,5);
for i=5:-1:1
    s(i) = ID(i);
end

It is always a good idea to provide a "default constructor" with no arguments, or at least use default values:

classdef ID < handle
    properties
        id
    end
    methods
        function obj = ID(id)
            if nargin<1, id = 0; end
            obj.id = id;
        end
    end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.