识别一行中的单元格输入

时间:2016-06-29 09:31:21

标签: matlab variadic-functions

考虑以下函数,其中输入为

>> 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的类而不是输入

2 个答案:

答案 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