2015-04-25 101 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); 

这些是比较极端案例,但要考虑的事情。