【问题标题】:Equality of structure objects结构对象的相等性
【发布时间】:2016-07-15 12:37:48
【问题描述】:

我在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 matlab-struct


    【解决方案1】:

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

    a = struct('a', 2);
    b = struct('b', a);
    
    a.a = 3
    
    % b.b.a == 2
    

    您实际上只能可靠地检查两个structs 的 是否相等。

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

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

    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
    

    更新

    另一种方法是为您的节点使用实际的handle 对象。一个基本的类应该是这样的。

    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
    

    【讨论】:

    • 我错过了这个。这就是为什么我的树修改代码不起作用的原因。你知道如何做一些事情,比如遍历一棵树并修改它吗?我找到的最接近的是:stackoverflow.com/questions/14793453/…
    • @TyanTowers 为什么不让您的节点成为实际的handle 对象?
    【解决方案2】:

    如果您正在搜索“reference-equality”,我猜您应该使用 handle 对象:

    当你想确定是否不同的句柄对象时使用 isequal 在所有对象属性中具有相同的数据。需要时使用 == 判断句柄变量是否引用同一个对象。

    treeTest.m

    function treeTest()
    
    root = TreeItem('Root');
    child = TreeItem('Child');
    grandChild = TreeItem('GrandChild');
    grandGrandChild = TreeItem('GrandGrandChild');
    grandGrandChild2 = TreeItem('GrandGrandChild');
    root.Children{end+1} = child;
    child.Children{end+1} = grandChild;
    grandChild.Children{end+1} = grandGrandChild;
    grandChild.Children{end+1} = grandGrandChild2;
    
    findItem(root, grandGrandChild2)
    
        function findItem(tree, childToFind)
            if ~numel(tree.Children)
                return;
            end
            disp(['Traversing in ', tree.Name]);
            for i=1:numel(tree.Children)
                disp(['Iteration step: ', num2str(i)])
                if tree.Children{i} == childToFind
                    disp(['Found! Name is ', tree.Children{i}.Name]);
                    return;
                end
                findItem(tree.Children{i}, childToFind);
    
            end
        end
    end
    

    TreeItem.m

    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
    

    如您所见,两个grand-grand-child 对象在属性方面是相等的,但输出中的Iteration step: 2 条目证明,第一个grand-grand-child 被跳过,因为函数正在搜索第二个。

    isequal==的区别:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多