假设a
被定义为下面的结构。我试图找到与R的dput相同的命令但是错误here。例如,我知道下面的格式必须是struct('const',1,'terms',{{struct(),struct()}})
,但我不知道结构中存储了什么,而不用像here这样的命令检查它,这很耗时。
那么我可以通过哪个命令看到在Matlab中生成结构的原始命令?
>> a
a =
const: 1
terms: {[1x1 struct] [1x1 struct]}
答案 0 :(得分:3)
<强>注释强>
您是否可以从使用结构切换到类?如果是这样,你可以创建一个模仿结构的模板,并且每次修改它时调用stack = dbstack来获取堆栈 - 然后将堆栈与更改一起存储。然后,可以从堆栈中的行号自动检索进行更改的命令。
作为评论中对此的后续请求,这里是一个提供结构功能的类的示例,并且还保留其分配的记录:
classdef utstruct
properties (SetAccess = private)
modifications
end
properties (Dependent, SetAccess = private)
myStruct
end
properties (Access = private)
m_struct
end
methods
function self = utstruct(varargin)
if nargin > 0
self.m_struct = builtin('struct', varargin{:});
else
self.m_struct = builtin('struct');
end
% Should update self.modifications here
end
function B = subsref(self, s)
if any(strcmp(s(1).subs, properties(self)))
B = builtin('subsref', self, s);
else
B = subsref(self.m_struct, s);
end
end
function A = subsasgn(self, s, b)
self.m_struct = subsasgn(self.m_struct, s, b);
newMod = builtin('struct');
newMod.type = 'subsasgn';
newMod.modData = {s b};
newMod.stack = dbstack;
self.modifications = [self.modifications; newMod];
A = self;
end
function disp(self)
disp(self.m_struct);
end
function names = fieldnames(self, varargin)
names = fieldnames(self.m_struct, varargin{:});
end
function C = cat(self, dim, varargin)
uts = cellfun(@(x)isa(x, 'utstruct'), varargin);
varargin{uts} = cellfun(@(x)x.m_struct, varargin(uts));
varargin = [{self.m_struct} varargin];
self.m_struct = cat(dim, varargin{:});
% Should update self.modifications here
C = self;
end
function C = horzcat(self, varargin)
C = self.cat(1, varargin{:});
end
function C = vertcat(self, varargin)
C = self.cat(2, varargin{:});
end
function value = get.myStruct(self)
value = self.m_struct;
end
end
end
在初始化/连接操作发生时,您应该添加一些代码来更新修改数组。
subsref
和subsasgn
覆盖是这里的关键点,使其行为像结构(通过将所有活动推迟到实际结构),但其他覆盖如fieldnames
和disp
做同样的事情。在subsasgn
中,保留了对结构的所有赋值的记录,以及生成赋值的堆栈。
注意:为了与内置struct
完全兼容,您可能应该覆盖更多方法,但这应该足以让您入门。请参阅Subclassing MATLAB Built-In Types。
编辑:我让这个例子更加健壮。它现在是一个价值类 - 应该是 - 并且与串联一起使用。
修改:您可以通过重新定义函数struct(...)
来避免使用查找和替换来重构现有的struct
调用:
function s = struct(varargin)
% STRUCT Overrides default struct function to provide unit-testable structs
%
% Set global variable unitTestStructEnabled to true to enable this
% function.
%
global unitTestStructEnabled;
if isempty(unitTestStructEnabled)
unitTestStructEnabled = false;
end
if unitTestStructEnabled
s = utstruct(varargin{:});
else
s = builtin('struct', varargin{:});
end
你可能不希望它一直在你的路径上闲逛,因为当你第一次创建一个结构时你会得到一个警告(你可以把它关闭,但这可能会隐藏其他问题),所以你可能应该将它放在通常不在路径中的文件夹中,并暂时将其添加到单元测试的路径中(addpath
/ rmpath
)。
答案 1 :(得分:1)
这是dumpvar
函数的骨架,即tashuhka
function str = dumpvar(a)
switch class(a)
case 'double'
if isempty(a)
str = '[]'; % bug when "a" is multidimensional and empty
elseif isscalar(a)
str = num2str(a);
elseif isrow(a)
str = strcat('[', dumpvar(a(1)));
for k = 2:size(a,2)
str = strcat(str,',',dumpvar(a(k)));
end;
str = strcat(str, ']');
elseif numel(size(a)) == 2
str = strcat('[', dumpvar(a(1,:)));
for k = 2:size(a,1)
str = strcat(str,';',dumpvar(a(k,:)));
end;
str = strcat(str, ']');
else
do_what_i_mean();
end;
case 'struct'
fn = fieldnames(a);
if isempty(fn)
str = 'struct()';
elseif isscalar(a)
str = strcat('struct(''', fn{1},''',', dumpvar(a.(fn{1})));
for k=2:numel(fn)
str = strcat(str,',''',fn{k},''',', dumpvar(a.(fn{k})));
end;
str = strcat(str, ')');
else
do_what_i_mean();
end;
otherwise
do_what_i_mean();
end;
function do_what_i_mean()
throwAsCaller(MException(...
'beingLazy:onSaturday:Fault', ...
'Storage of class "%s" and arity %d is not implemented yet. Would you?', ...
class(a), numel(size(a))...
));
end;
end
将其保存在Matlab路径中某处的dumpvar.m
文件中,然后使用以下代码片段对其进行测试:
a = struct(...
'field1', 1,...
'field2', [],...
'field10', struct(...
'field3', [1 2;2 3;3 4],...
'field4', struct()...
)...
);
disp(dumpvar(a));
eval(sprintf('b=%s;', dumpvar(a)));
请注意,此功能仍处于玩具阶段:它几乎无所不包(缺少对结构数组,单元格,字符,逻辑和其他基本类型的处理,更不用说用户定义的类了 - 呵呵,那些会是一个泡菜)它是由你完成你需要的任何功能。
答案 2 :(得分:1)
虽然它没有完全回答你的问题,但是Urs的vsize()可以帮助你:
% Create some complicated variable
v(1).a{1}=sparse(magic(3)+2i*magic(3));
v(2).a{2}={struct('FA',{'a','bb'},'FB',{magic(5),{}})};
v(2).b{2}=@(x) sind(x);
% Dissect
P = vsize(v);
% -------------------------
% 1998 1998 B * v = 2:1x2:struct.(2)
% CELL ----- 360 B v[].a = 2:1x1:cell
% 1750 248 B - v[].a{} = 2:3x3:double.sparse.complex
% CELL ----- 1014 B v[].a = 2:1x2:cell
% 1750 0 B - v[].a{} = 2:0x0:double
% CELL ----- 894 B v[].a{} = 2:1x1:cell
% STRUCT --- 782 B v[].a{}{} = 2:1x2:struct.(2)
% 1748 2 B - v[].a{}{}[].FA = 2:1x1:char
% 1744 4 B - v[].a{}{}[].FA = 2:1x2:char
% 1544 200 B - v[].a{}{}[].FB = 2:5x5:double
% CELL ----- 0 B v[].a{}{}[].FB = 2:0x0:cell
% 1544 0 B - v[].b = 2:0x0:double
% CELL ----- 152 B v[].b = 2:1x2:cell
% 1544 0 B - v[].b{} = 2:0x0:double
% 1512 32 B - v[].b{} = 2:1x1:function_handle