结构对象的相等性
Equality of structure objects
我在matlab中有这样一个树结构:
node =
sub: [1x4 struct]
其中每个子节点也是一个节点。
node.sub(1) =
sub: [1x4 struct]
等叶节点有空子。假设我有一个节点并且我正在遍历树。有什么方法可以检查节点 'object' 是否与树中的任何节点相同?我不是在谈论价值相同。我希望 'object' 相同。
例如:
mynode = tree.sub(1).sub(1);
isobjectequal(mynode, tree.sub(1).sub(1))
A struct
在 MATLAB 中从技术上讲并不是您所说的 "object"。如果我创建一个结构,然后将其分配为另一个结构中的一个字段,则两者现在是解耦的。对第一个结构所做的任何更改都不会反映在我们刚刚制作的副本中。
a = struct('a', 2);
b = struct('b', a);
a.a = 3
% b.b.a == 2
您实际上只能可靠地检查两个 struct
的 值 是否相等。
如果您真的想验证您正在比较的两个 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
更新
另一种方法是为您的节点使用实际的 handle
对象。基本的 class 看起来像这样。
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
如果您要搜索 "reference-equality",我想您应该使用 handle 个对象:
Use isequal when you want to determine if different handle objects
have the same data in all object properties. Use == when you want to
determine if handle variables refer to the same object.
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
如您所见,两个曾孙对象在属性方面是相等的,但是输出中的 Iteration step: 2
条目证明第一个曾孙对象被跳过了,因为函数正在搜索第二个。
isequal
和==
的区别:
>> grandGrandChild = TreeItem('GrandGrandChild');
grandGrandChild2 = TreeItem('GrandGrandChild');
>> isequal(grandGrandChild, grandGrandChild2)
ans = 1
>> grandGrandChild == grandGrandChild2
ans = 0
我在matlab中有这样一个树结构:
node =
sub: [1x4 struct]
其中每个子节点也是一个节点。
node.sub(1) =
sub: [1x4 struct]
等叶节点有空子。假设我有一个节点并且我正在遍历树。有什么方法可以检查节点 'object' 是否与树中的任何节点相同?我不是在谈论价值相同。我希望 'object' 相同。
例如:
mynode = tree.sub(1).sub(1);
isobjectequal(mynode, tree.sub(1).sub(1))
A struct
在 MATLAB 中从技术上讲并不是您所说的 "object"。如果我创建一个结构,然后将其分配为另一个结构中的一个字段,则两者现在是解耦的。对第一个结构所做的任何更改都不会反映在我们刚刚制作的副本中。
a = struct('a', 2);
b = struct('b', a);
a.a = 3
% b.b.a == 2
您实际上只能可靠地检查两个 struct
的 值 是否相等。
如果您真的想验证您正在比较的两个 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
更新
另一种方法是为您的节点使用实际的 handle
对象。基本的 class 看起来像这样。
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
如果您要搜索 "reference-equality",我想您应该使用 handle 个对象:
Use isequal when you want to determine if different handle objects have the same data in all object properties. Use == when you want to determine if handle variables refer to the same object.
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
如您所见,两个曾孙对象在属性方面是相等的,但是输出中的 Iteration step: 2
条目证明第一个曾孙对象被跳过了,因为函数正在搜索第二个。
isequal
和==
的区别:
>> grandGrandChild = TreeItem('GrandGrandChild');
grandGrandChild2 = TreeItem('GrandGrandChild');
>> isequal(grandGrandChild, grandGrandChild2)
ans = 1
>> grandGrandChild == grandGrandChild2
ans = 0