简体   繁体   English

Matlab:按属性建立对象数组索引

[英]Matlab : Object array indexing by property

In Matlab, I would like to create an array of objects from where I can pick up an element by one of its unique property while keeping the same behavior as normal indexing. 在Matlab中,我想创建一个对象数组,从中可以通过其唯一属性之一拾取元素,同时保持与普通索引相同的行为。

Here is the 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

Lets consider the following array : 让我们考虑以下数组:

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

The easiest way to directly acess to the values of an element is : 直接访问元素值的最简单方法是:

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

But I would like to call the elements of the array by their name not their index, while keeping the ability to have a direct access to the values : 但是我想通过名称而不是索引来调用数组的元素,同时保持直接访问值的能力:

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

I could une two = findobj(a,'Name','two'); two.Values(end-2:end) * 3 我可以找到two = findobj(a,'Name','two'); two.Values(end-2:end) * 3 two = findobj(a,'Name','two'); two.Values(end-2:end) * 3 but it's not as convinient. two = findobj(a,'Name','two'); two.Values(end-2:end) * 3但是不那么方便。

I've tried setting a custom subsref method to my object and it works quite well but I lose some indexing features. 我尝试为我的对象设置一个自定义subsref方法,效果很好,但是我失去了一些索引功能。

I got the intended behavior with the following method : 我通过以下方法获得了预期的行为:

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

But I can't get all the names/values with [a.Values] or {a.Name} . 但是我无法使用[a.Values]{a.Name}来获取所有名称/值。 Matlab returns : Matlab返回:

Error using myClass/subsref
Too many output arguments.

And I might lose other indexing features as well. 而且我可能还会失去其他索引功能。

Is there a better solution for my problem ? 我的问题有更好的解决方案吗? Any help would be appreciated. 任何帮助,将不胜感激。

You can use a varargout in subsref to support getting a list of all the values of the property Values : 您可以在varargout中使用subsref来支持获取属性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

Note that I also added ~strcmp(S(1).subs{1},':') to the condition in the first if to support a(:) indexing. 请注意, if支持a(:)索引,我还会在第一个条件中添加~strcmp(S(1).subs{1},':')

One other consideration I see is how to handle multiple strings: 我看到的另一个考虑因素是如何处理多个字符串:

a('one','two');

or mixed types: 或混合类型:

a('one',3:end);

These are more corner cases, but something to consider. 这些是更多的极端情况,但是需要考虑一些事项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM