MATLAB有任何类似集合的数据类型吗?

3

我正在寻找一种在MATLAB中比较具有非确定性排序的有限序列数据的方法。基本上,我想要一个数组,但不对其中包含的元素施加顺序限制。如果我有这些对象:

a = [x y z];

并且

b = [x z y];

我希望isequal(a, b)返回true。但当涉及到数组时,情况并非如此。解决方法是在比较之前对条目进行排序,然而,在我的情况下,元素是复杂对象,它们不能轻易地映射为彼此具有明确的数字关系。另一种方法是不使用isequal,而是使用自定义比较函数,该函数断言匹配长度,然后仅检查第一个数组中的每个元素是否包含在第二个数组中。但是,在我的情况下,通过isequal比较的数组是嵌套在我正在尝试比较的结构体中的,编写封装结构体的自定义比较函数将非常复杂。除了这个排序问题之外,内置的isequal函数涵盖了我所有的需求,因为它正确处理任意嵌套的结构体和任意字段,所以我真的想避免为此编写一个复杂的自定义函数。 MATLAB中是否有允许上述行为的数据类型?还是有一种简单的方法来构建这样的自定义类型?在Java中,我可以编写一个包装器类,并为equals方法编写自定义实现,但是在MATLAB中似乎没有这样的机制?

2
如果isequal除了顺序外符合您的需求,您不能做类似这样的事情吗?:a = {[20 20 30], 'abc', {[1 2]; [3:4]}}; b = a; [aa, bb] = ndgrid(a, a); m = arrayfun(@isequal, aa, bb), result = all(any(m,1))&all(any(m,2)) 它遵循了您测试一个数组中的每个元素与另一个数组中的每个元素(通过调用isequal)的想法,这可能是时间效率低下的。当然,您可以将ndgrid替换为两个for循环以增加内存效率,并且如果另一个数组中缺少元素,则可以提前退出以增加时间效率。 - Luis Mendo
1
我有点困惑。如果你说isequal除了顺序外都有效,那么我使用isequal的方法也应该有效,包括嵌套等,对吧?我在想像下面这样的东西。无论如何,如果尺寸的乘积太大,以至于尝试所有元素对是不切实际的。 - Luis Mendo
1
(https://tio.run/##jVLBTsMwDL3nK3xBS0WH1o1TKz6Ab6h6cDKXRaQJpCkIpvHrxam0bgUOWFWT@vnFL371OuIbjWM7OB2NdxCoH2yEBzA9vQ5otxJzUJkw7Tkje/NJErMcpo3KMgEcMzGGgSq4gdYHcP79Dh4jdObpEEGR9h1Bi7aniZNKDDKnKN3QkeVTp/yMqStMXbAU@qJRojRJj5KG1VSLMtatF4kUKhA@s8RIoTMOI4FxjgJY71@AMNiPknWt4wHIUkcuMg7I7dKqFseR24u/9tz3Sy9a@CH@q4Xz8XebebrT8JZXnG7zS0Ra6Tzon/QJdHvWl95n84VIXhzr7Qb42W2aHFao9CrnXAHbpoJ6V943p1MlkjFYgToy/7Y48VfdVELMhuTAVl7/Qii5slwXZZEtgRoBm@yayUaP4zc) - Luis Mendo
2
isempty(setdiff(a,b)) 不起作用吗? - beaker
1
进一步解释beaker的评论:MATLAB使用函数(例如setdiffismemberintersectunion等)进行集合操作。但我不知道这些函数是否适用于非可排序值,甚至是否适用于非数值矩阵。 - Cris Luengo
显示剩余6条评论
1个回答

1

我找到了一种优雅地解决我的问题的方法。与我之前所说的信念相反,MATLAB实际上允许类特定的覆盖isequal

classdef CustomType
    properties
        value
    end

    methods
        function self = CustomType(value)
            self.value = value;
        end

        function equal = isequal(self, other)
            if not(isa(other, 'CustomType'))
                equal = false;
                return;
            end

            % implement custom comparison rules here
        end
    end
end

所以,我可以像这样简单地分配相关的字段,而不必更改我的代码中的任何其他内容:
a = Set([x y z]); % custom type
...
b = Set([x z y]);
...
isequal(a, b); % true

在我的使用场景中,我甚至不需要集合的唯一性属性。因此,我只需要执行无序比较,而且不需要浪费性能来确保不必要的属性。此外,通过使用专用类型,我可以在赋值时明确区分具有顺序的字段(即常规数组)和没有顺序的字段。
另一个解决方案可能是覆盖内置的isequal函数,并在其参数为特定类型时应用自定义比较规则。然而,这会减慢整个程序中的所有比较速度,并导致封装性差。我认为使用具有重写的 isequal 函数的自定义类型是解决这种问题的方法。但我仍然认为集合(和其他类型的常用容器)应包含在 MATLAB 的基本库中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接