考虑以下函数,其中输入为
>> b.a = 1
b =
a: 1
>> c = {'this' 'cell'}
c =
'this' 'cell'
>> d = [1 2 3]
d =
1 2 3
可以通过多种方式调用输入,例如testfunction(b,d,c)
testfunction(d,c,b)
等我想获取单元格输入并从中检索一些数据
function testfunction(varargin)
for i =1:numel(varargin)
if(iscell(varargin{i}))
fprintf('The input number %d is a cell!\n',i)
end
end
识别变量输入是否是一个单元格,但是有没有优雅的方法呢?因为iscell
没有返回索引,我也使用class()
但它返回varargin
的类而不是输入
答案 0 :(得分:2)
这里的主要问题不是性能,而是可读性和漂亮的代码。
我建议您创建一个单独的函数来检查单元格的位置,并在主函数中调用该函数。这样,您可以在一行中检查单元格的位置。它简单,快速,易于阅读。既然您可以在编辑器中保存函数并关闭脚本,那就像调用内置单行程序一样。该函数还可以进行其他输入检查。
示例功能:
function idx = cell_index(C)
idx = 0;
if isempty(C)
warning('No input was given.')
else
for ii = 1:numel(C)
if(iscell(C{ii}))
idx = ii;
end
end
end
if idx == 0
warning('The input contained no cells.')
end
end
现在,您可以在主要功能中执行以下操作:
function output = main_function(varargin)
idx = cell_index(varargin)
fprintf('The input number %d is a cell!\n', idx)
%
% or fprintf('The input number %d is a cell!\n, cell_index(varargin))
% Rest of code
**循环与其他方法:**
让我们尝试一些功能:
Appraoach 1:循环
这是最快的一个:
function s = testfunction1(varargin)
for ii = 1:numel(varargin)
if(iscell(varargin{ii}))
s = sprintf('The input %i is a cell!\n', ii);
end
end
end
方法2:cellfun
这是最慢和最难阅读的(IMO):
function s = testfunction2(varargin)
if any(cellfun(@(x) iscell(x),varargin))
s = sprintf('The input %s is a cell\n', num2str(find(cellfun(@(x) iscell(x),varargin))));
end
end
方法3:cellfun
这是最容易的,假设你不想要循环
function s = testfunction3(varargin)
x = find(cellfun(@(x) iscell(x),varargin));
if ~isempty(x)
s = sprintf('The input %i is a cell \n',x);
end
end
在使用新的JIT引擎之前,使用Matlab R2014b执行以下基准测试!
f = @() testfunction1(b,c,d);
g = @() testfunction2(b,c,d);
h = @() testfunction3(b,c,d);
timeit(f)
ans =
5.1292e-05
timeit(g)
ans =
2.0464e-04
timeit(h)
ans =
9.7879e-05
<强>要点:强>
如果你想使用无循环方法,我建议使用最后一种方法(第二个cellfun
版本)。这只会执行一次find
和一次cellfun
的调用。因此它更容易阅读,而且速度更快。
答案 1 :(得分:1)
在这种情况下不确定循环避免,但这应该可以解决问题。
testfunction(b,c,d)
testfunction(b,c,d,c)
testfunction(b,d)
function testfunction(varargin)
if any(cellfun(@(x) iscell(x),varargin))
fprintf(['The input(s) ' num2str(find(cellfun(@(x) iscell(x),varargin))) ' is (are) cell \n']);
end
end