Functional programming construct to expand cell array into arguments for other functions without using an intermediate variable in the (user) code?
13 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Christian Ridderström
el 12 de Ag. de 2021
Comentada: Christian Ridderström
el 14 de Ag. de 2021
I'm looking for a functional programming construct. The construct should let me use a cell array, e.g. returned from a function, as separate arguments to another function -- without (the user) having to create an intermediate variable.
Example: Let's say I have two objects (tables), T1 and T2, for which I'd like to compare different properites (e.g. size, variable names). I could do it as follows (doing the example for just one property):
property_1 = @(T) T.Properties.VariableNames;
C = cellfun(property_1, { T1, T2 }, 'UniformOutput', 0); % (1)
assert(isequal(C{:})); % (2)
However, I'd like a way to achieve (1) and (2) without assigning to the intermediate variable, 'C'. Unfortunately the following code doesn't work:
assert(isequal(cellfun(varnames, { T1, T2 }, 'uni', 0){:}));
Is it possible to write a helper function 'foo' that would allow this code:
assert(isequal(foo(result)))
Or must there instead be another type of helper function, 'bar', that's used along the following lines:
assert(bar(@isequal, result))
function [varargout] = bar(fcn, C)
[varargout{1:nargout}] = fcn(C{:});
end
If I can only do the latter, any suggestions for the name of 'bar'?
2 comentarios
J. Alex Lee
el 12 de Ag. de 2021
Editada: J. Alex Lee
el 12 de Ag. de 2021
is there a reason not mentioned here that you must use this cell array route, rather than a strategy such as
function assertPairwisePropertyEquality(A,B,PropName)
PropA = A.Properties.(PropName);
PropB = B.Properties.(PropName);
assert(isequal(PropA,PropB))
end
Or maybe
propFcn = @(obj)(obj.Properties.VariableNames);
% propFcn = @(obj)(height(obj));
function assertPairwisePropertyEquality(A,B,fcn)
PropA = fcn(A);
PropB = fcn(B);
assert(isequal(PropA,PropB))
end
Respuesta aceptada
Stephen23
el 12 de Ag. de 2021
Editada: Stephen23
el 12 de Ag. de 2021
The closest is to use the new syntax which allows dot indexing directly into function outputs:
For example:
fprintf('%d\n',testfun().X)
function S = testfun()
S(1).X = 123;
S(2).X = 456;
S(3).X = 789;
end
Otherwise the reason why your approach will not work is already explained in detail in this comment (and thread):
5 comentarios
Más respuestas (2)
J. Alex Lee
el 13 de Ag. de 2021
Editada: J. Alex Lee
el 13 de Ag. de 2021
I am still not sure why you can't just have your generalized comparator function saved as a function somewhere on your path so you can reference it often...but anyway, "apply_expand" is still an intermediary, though you do accomplish it inline...
With @Stephen Cobeldick's insight, I thnk you could as well do (it would be just as cumbersome but you can at least remove one anonymous function definition)
isequal(cell2struct(cellfun(property_1, { T1, T2 }, 'UniformOutput', 0),"myprop").myprop)
To me, it all points to the more upstream question of why you can dot-index, but not brace-index into function calls...it doesn't seem at all silly to expect that it should work, and it seems to me that many questions along the lines of the actual question here (as well as the linked one) might ultimately derive from this inability.
2 comentarios
Christian Ridderström
el 14 de Ag. de 2021
Editada: Christian Ridderström
el 14 de Ag. de 2021
Ver también
Categorías
Más información sobre Loops and Conditional Statements 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!