Matlab 结构对象的相等性

Matlab 结构对象的相等性,matlab,matlab-struct,Matlab,Matlab Struct,我在matlab中有一个树结构,如下所示: node = sub: [1x4 struct] 其中每个子节点也是一个节点 node.sub(1) = sub: [1x4 struct] 等。叶节点有空的子节点。假设我有一个节点,我正在向下遍历树。是否有方法检查节点“对象”是否与树中的任何节点相同?我不是说价值是一样的。我希望“对象”是相同的 例如: mynode = tree.sub(1).sub(1); isobjectequal(mynode, tree.sub(1).su

我在matlab中有一个树结构,如下所示:

node = 
  sub: [1x4 struct]
其中每个子节点也是一个节点

node.sub(1) = 
   sub: [1x4 struct]
等。叶节点有空的子节点。假设我有一个节点,我正在向下遍历树。是否有方法检查节点“对象”是否与树中的任何节点相同?我不是说价值是一样的。我希望“对象”是相同的

例如:

mynode = tree.sub(1).sub(1);
isobjectequal(mynode, tree.sub(1).sub(1))

MATLAB中的
struct
从技术上讲并不是您所说的“对象”。如果我创建一个结构,然后将其指定为另一个结构中的字段,那么这两个结构现在是不耦合的。对第一个结构所做的任何更改都不会反映在我们刚才所做的副本中

a = struct('a', 2);
b = struct('b', a);

a.a = 3

% b.b.a == 2
您实际上只能可靠地检查两个
struct
s的值是否相等

如果确实要验证正在比较的两个
struct
是以相同的方式创建的,则可以递归地遍历
struct
,并确定两个结构中每个元素的属性是否相同。这意味着结构是相等的,并且它们是使用相同的基础数据创建的

对于一个非常简单的非深度嵌套结构,它可能看起来像这样

function bool = isSameStruct(A, B)

    fmt = get(0, 'Format');

    format debug;
    memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match');

    if isequaln(A, B)
        bool = true;
    elseif ~isequal(sort(fieldnames(A)), sort(fieldnames(B)))
        bool = false;
    else
        fields = fieldnames(A);

        bool = true;

        for k = 1:numel(fields)
            if ~isequal(memoryLocation(A.(fields{k})), memoryLocation(B.(fields{k})))
                bool = false;
                break;
            end
        end
    end

    format(fmt);
end
classdef Node < handle
    properties
        Value
        Children
    end

    methods
        function self = Node(value)
            self.Value = value;
        end

        function addChild(self, node)
            self.Children = cat(2, self.Children, node)
        end
    end
end
如果您正在搜索“引用相等”,我想您应该使用对象:

如果要确定是否有不同的句柄对象,请使用isequal 在所有对象属性中具有相同的数据。如果需要,请使用== 确定句柄变量是否引用同一对象

treeTest.m

TreeItem.m

正如您所看到的,两个grand grand child对象在属性方面是相等的,但是输出上的
迭代步骤:2
条目证明,第一个grand child被跳过,因为函数正在搜索第二个grand child

=
之间的差异是相等的:

>> grandGrandChild = TreeItem('GrandGrandChild');
grandGrandChild2 = TreeItem('GrandGrandChild');
>> isequal(grandGrandChild, grandGrandChild2)

ans =    1

>> grandGrandChild == grandGrandChild2

ans =   0

我错过了这个。这就是我的树修改代码不起作用的原因。你知道如何遍历一棵树并修改它吗?我发现的最接近的是:@TyanTowers为什么不让你的节点成为实际的
句柄
对象?
classdef TreeItem < handle
    properties
        Name;
        Children;
    end

    methods
        function obj = TreeItem(name)
            obj.Name = name;
            obj.Children = {};
        end 
    end
end
Traversing in Root
Iteration step: 1
Traversing in Child
Iteration step: 1
Traversing in GrandChild
Iteration step: 1
Iteration step: 2
Found! Name is GrandGrandChild
>> grandGrandChild = TreeItem('GrandGrandChild');
grandGrandChild2 = TreeItem('GrandGrandChild');
>> isequal(grandGrandChild, grandGrandChild2)

ans =    1

>> grandGrandChild == grandGrandChild2

ans =   0