Matlab:对象数组索引 属性

Matlab : Object array indexing by property

在 Matlab 中,我想创建一个对象数组,从中我可以通过其唯一 属性 之一选取一个元素,同时保持与正常索引相同的行为。

这里是 class:

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

但我想通过名称而不是索引来调用数组元素,同时保持直接访问值的能力:

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

我可以 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} 获得所有 names/values。 Matlab returns :

Error using myClass/subsref
Too many output arguments.

而且我可能还会失去其他索引功能。

我的问题有更好的解决方案吗? 任何帮助将不胜感激。

您可以在 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);

这些是更多的极端情况,但需要考虑。