2016-06-29 1 views
1

私は、セルの入力を取得し、そこからいくつかのデータを取得する入力が1行でセル入力を認識

>> 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インデックスを戻らdoesntのため、私はまたclass()を使用しますが、それはvararginのクラスの代わりに、入力

答えて

2

ここでの主な問題は、パフォーマンスではなく読みやすさときれいなコードです。

セルがどこにあるかをチェックし、メイン関数でその関数を呼び出す別の関数を作成することをお勧めします。この方法で、セルがどこにあるかを1行で確認できます。シンプルで、速く、読みやすい。関数を保存してエディタでスクリプトを閉じるだけで、組み込みの1行を呼び出すようになります。この機能は、他の入力チェックを行うこともできます。

例機能:

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:Loop

これは最速のものである:

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:セルフン

これは、ループ

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 

概要:

あなたはループのないアプローチを使用したい場合は、私は最後のアプローチ(第2 cellfunバージョン)をお勧めします。これは、findを1つだけ実行し、cellfunを1回だけ実行します。したがって、読みやすく、速くなります。

+0

Griffen:こんにちは、私はあなたの答えを喜んで受け入れますが、私はすでにforループのラッパー関数である 'cellfun'も知っていました。 'ismember'のような関数から索引を得る方法があるかどうかを知りたがっていました。私の質問を正しく説明できなかったのでしょうか? – Umar

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 
+0

cellfunはforループのためのラッパー関数です:)とにかく+1 – Umar

+0

井戸ですが、 '1行でセル入力を認識しています')。しかし、私はあなたのポイントを取得し、私は再び試してみます。常に正確に3つの入力がありますか? – Finn

+0

入力数が100であっても1つはセルである – Umar

関連する問題