3

如果我有这样的价值类:

classdef MyVal
    properties
        foo
    end
    methods 
        function self = MyVal(varargin)
            if nargin > 0
                self.foo = varargin{1};
            end
        end
    end
end

并在表格中使用它:

foo(1) = MyVal(1); foo(2) = MyVal(2);
t = table(foo')

输出是:

t =

  2×1 table

       Var1    
    ___________

    [1×1 MyVal]
    [1×1 MyVal]

是否有任何必须在MyVal(或表的任何属性)中定义的方法允许更改表中值的表示?我不想转换传递给的数据,table因为我想检索MyVal我在表中建立索引的实例。

4

2 回答 2

4

您可以为table. 这有点棘手,因为 MATLAB 不允许您从table该类继承,但通过重载subsrefandsubsasgn运算符,您无论如何都可以获得大部分功能......

我在这个答案的底部包含了这个类,因为它有点长,用法如下所示:

>> foo(1) = MyVal(1); foo(2) = MyVal(2);
>> t = MyTable(foo') % Omitting the ";" calls our overloaded "disp" function
t = 
    Var1
    ____
    1   
    2   

您也可以使用它来提取数字数据(即foo与其他数据一起使用的属性)t.numeric,尽管我怀疑您需要将table2array其用于与 一起使用uitable,就像使用普通的table.

classdef MyTable
    properties ( Access = private )
        table_
    end
    properties ( Dependent = true )
        numeric
    end
    methods % Constructor and getter
        function obj = MyTable( varargin )
            % Store as a normal table internally
            obj.table_ = table( varargin{:} );
        end 
        function num = get.numeric( obj )
            % By calling obj.numeric, output the table but with MyVal
            % objects replaced by their "foo" property.
            % This could be passed into a uitable, and is used in disp()
            cls = varfun( @(x)isa(x,'MyVal'), obj.table_, 'OutputFormat', 'uniform' );
            num = obj.table_;
            for ii = find(cls)
                num.(num.Properties.VariableNames{ii}) = [num.(num.Properties.VariableNames{ii}).foo].';
            end            
        end
    end
    methods % Overloaded to emulate table behaviour        
        function disp( obj )
            % Overload the disp function (also called when semi colon is
            % omitted) to output the numeric version of the table
            disp( obj.numeric );
        end
        % Overload subsref and subsasgn for table indexing
        function varargout = subsref( obj, s )
            [varargout{1:nargout}] = builtin( 'subsref', obj.table_, s );
        end
        function obj = subsasgn( obj, s, varargin )
            obj.table_ = builtin( 'subsasgn', obj.table_, s, varargin{:} );
        end    
        % Have to overload size and isa for workspace preview
        function sz = size( obj, varargin )
            sz = size( obj.table_, varargin{:} );
        end
        function b = isa( obj, varargin )
            % This is only OK to do because we overloaded subsref/subsasgn
            b = isa( obj.table_, varargin{:} );
        end        
    end
end
于 2021-02-12T09:23:39.170 回答
2

只回答了一半

我找不到自定义table对象显示的方法,但是如果您可以通过使用arrays对象来获得,那么有一种方法,在为类自定义对象显示中进行了描述。

对于您的示例,您必须使用: 派生您的类matlab.mixin.CustomDisplay,然后覆盖该displayNonScalarObject方法:

classdef MyVal < matlab.mixin.CustomDisplay
    properties
        foo
    end
    methods
        function self = MyVal(varargin)
            if nargin > 0
                self.foo = varargin{1};
            end
        end
    end
    
    methods (Access = protected)
        function displayNonScalarObject(objAry)
            dimStr = matlab.mixin.CustomDisplay.convertDimensionsToString(objAry);
            cName = matlab.mixin.CustomDisplay.getClassNameForHeader(objAry);
            headerStr = [dimStr,' ',cName,' members:'];
            header = sprintf('%s\n',headerStr);
            disp(header)
            for ix = 1:length(objAry)
                o = objAry(ix);

                % OPTION 1:
                % For a class with a sinle property, no need to call the
                % big guns, just build your own display:
                disp( [num2str(ix) ': foo = ' num2str(o.foo) ] ) ;
                
                % OR OPTION 2: (comment option1 if you use this)
                % If your class had multiple properties and you want to
                % display several of them, use the MATLAB built-in functions:
                
                % create a structure with the property names you need
                % displayed:
%                 propList = struct('foo',o.foo,'prop2',o.prop2,'prop3',o.prop3);
                % Then let MATLAB handle the display
%                 propgrp = matlab.mixin.util.PropertyGroup(propList);
%                 matlab.mixin.CustomDisplay.displayPropertyGroups(o,propgrp);
            end
        end  
    end
end

现在,如果您构建类的数组,显示将如下所示:

>> foo(1) = MyVal(1); foo(2) = MyVal(2);
>> foo
foo = 
1x2 MyVal members:

1: foo = 1
2: foo = 2

当然,这只是一个示例,并且是高度可定制的。不幸的是,我找不到一种方法来使它适用于table对象。

于 2021-02-12T08:50:51.557 回答