Implementing 'curly' and 'access' “chaining” functions in matlab

六眼飞鱼酱① 提交于 2019-12-01 20:51:37

Disclaimer: Less of an answer and more of some random musings

The issue here is that, in MATLAB, a single function (anonymous or otherwise) is incapable of returning a comma-separated list the way that dot referencing and {} indexing can.

Even MATLAB's internal functions for performing the referencing are incapable of doing so:

subsref(S, substruct('.', 'name'))
%   john

builtin('_dot', S, 'name')              % Only works pre-2015b
%   jim

subsref(C, substruct('{}', {3 ':'}))
%   3

builtin('_brace', C, 3, ':')            % Only works pre-2015b
%   3

But what a single function can do in MATLAB, is return multiple outputs. This is precisely how subsref and the other built-ins return the multiple values you're hoping for

S = struct('name', {'john', 'jim'});

[val1, val2] = subsref(S, substruct('.', 'name'));
[val1, val2] = builtin('_dot', S, 'name');

C = num2cell(magic(3));

[val1, val2, val3] = subsref(C, substruct('{}', {3, ':'}));
[val1, val2, val3] = builtin('_brace', C, 3, ':');

Now this doesn't really help your helper anonymous function since it requires knowledge of how many outputs to expect and that in turn depends on the inputs.

For your acces function, it's relatively straight forward to determine the number of outputs so you could easily do something like:

[A{1:numel(S)}] = acces(S, 'name');

Unfortunately, you can't do that inside of an anonymous function, and there's also no easy way to get a non-cell array out apart from wrapping this with a follow-up call to cell2mat

[A{1:numel(S)}] = acces(S, 'name');
A = cell2mat(A);

You could create some anonymous functions to do these various operations, but they are messy.

access_cell = @(s,n)arrayfun(@(x)acces(x,n), s, 'uniform', 0);
access_array = @(s,n)arrayfun(@(x)acces(x,n), s, 'uniform', 1);

As for your curly you could instead use paren to grab a subset of the cell array as a cell and then loop through it with cellfun to yield the result.

% This is really just using parenthesis
curly_sequence_cell = paren;

curly_sequence_array = @(varargin)cell2mat(paren(varargin{:}));

But the real solution is just use a temporary variable and then index into that using the typical MATLAB syntax :)

S = struct('name', {'john', 'jim'});
A = {S.name};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!