2015-04-25 142 views
1

在Matlab中,我想創建一個對象數組,使其可以通過其獨特屬性獲取元素,同時保持與正常索引相同的行爲。Matlab:按屬性對象數組索引

下面是類:

classdef myClass < dynamicprops 

    properties 
     Name = ''; 
     Values 
    end 

    methods 
     function obj = myClass(name,values) 
      if nargin > 0 
       obj.Name = name; 
       obj.Values = values; 
      end 
     end 
    end 
end 

讓我們考慮以下的數組:

>> a(1) = myClass('one' ,[1:10]); 
>> a(2) = myClass('two' ,[2:20]); 
>> a(3) = myClass('three',[3:30]); 

直接接取到的元素的值的最簡單方法是:

>> a(1).Values 
ans = 
1  2  3  4  5  6  7  8  9 10 

但我想通過他們的名字而不是他們的索引來調用數組的元素,同時保留abilit Ÿ有直達值:

>> % /!\ This is intended behavior, not real result 
>> a('two').Values(end-2:end) * 3 
ans = 
    54 57 60 

我可以UNE two = findobj(a,'Name','two'); two.Values(end-2:end) * 3但它不是爲方便易。

我試着設置一個自定義的subsref方法到我的對象,它工作得很好,但我失去了一些索引功能。

我用下面的方法預期的行爲:

function out = subsref(obj,S) 
    if strcmpi(S(1).type,'()') && ischar(S(1).subs{1}) 
     found = findobj(obj,'Name',S(1).subs{1}); 
     if ~numel(found) 
      error(['Object with Name ''' S(1).subs{1} ''' not found.']) 
     end 
     if numel(S) == 1 
      out = found(1); 
     else 
      out = builtin('subsref',found(1),S(2:end)); 
     end 
    else 
     out = builtin('subsref',obj,S); 
    end 
end 

但我不能[a.Values]{a.Name}獲得的所有名稱/值。 Matlab的回報:

Error using myClass/subsref 
Too many output arguments. 

而且我可能會失去其他索引功能,以及。

對我的問題有更好的解決方案嗎? 任何幫助,將不勝感激。

回答

0

可以在subsref使用varargout支持獲取屬性Values的所有值的列表:

function varargout = subsref(obj,S) 
    if strcmpi(S(1).type,'()') && ischar(S(1).subs{1}) && ... 
     ~strcmp(S(1).subs{1},':') 
     found = findobj(obj,'Name',S(1).subs{1}); 
     if ~numel(found) 
      error(['Object with Name ''' S(1).subs{1} ''' not found.']) 
     end 
     if numel(S) == 1 
      varargout{1} = found(1); 
     else 
      varargout{1} = builtin('subsref',found(1),S(2:end)); 
     end 
    else 
     [varargout{1:nargout}] = builtin('subsref',obj,S); 
    end 
end 

注意,我也在第一if添加~strcmp(S(1).subs{1},':')的條件來支持a(:)索引。

另一個考慮我看到的是如何處理多個字符串:

a('one','two'); 

或混合類型:

a('one',3:end); 

這些是比較極端案例,但要考慮的事情。