【问题标题】:MATLAB containers.Map with tuple as keyMATLAB containers.Map 以元组为键
【发布时间】:2017-09-07 18:56:28
【问题描述】:

我想创建一个containers.Map 对象,它使用一个元组,例如[4,1],作为键。但是,这不是有效的密钥类型。如何将其转换为有效的密钥类型?

我的最终目标是拥有像稀疏元胞数组这样的东西,我可以像矩阵一样索引它,但可以存储任意对象。

【问题讨论】:

  • 不能使用二维元胞数组吗?
  • 是的,但是如果元胞数组的总范围很大(每边有数千个),我会担心内存使用情况
  • 如果你想要一些行为类似于稀疏元胞数组的东西,请实现一个行为类似于稀疏元胞数组的类,不要滥用containers.Map。例如,只需有一个类,其中包含一个稀疏索引数组作为一个属性,一个单元格数组作为另一个属性,然后在该类上重载 subsref,以便在对它进行索引时得到正确的东西。跨度>
  • 我想出的解决方案是创建一个 2D sparse array A 并使用元组键作为索引存储 A(4,1)=my_val 之类的值;可能不是最快的。

标签: matlab dictionary


【解决方案1】:

作为 cmets,我收到了很多答案,所以为了后代(以及我自己的理智),我将这些作为实际答案写下来。

元组通过sub2ind标量

如果您尝试模拟具有已知大小的稀疏矩阵的行为,则可以使用 sub2ind 将任何有效元组转换为唯一线性索引。

例如,如果您假设的稀疏元胞数组大小为 1000 x 200,那么您可以这样做:

sp_cell = containers.Map('KeyType','double', 'ValueType','any');
key_converter = @(i,j) sub2ind([1000,200], i,j);
sp_cell(key_converter(4,1)) = 'foo';

通过mat2str 到字符串的元组

或者(更一般地),您可以使用mat2str 将您的元组转换为字符串,但是您将失去sub2ind 提供的对数组索引边界的检查:

sp_cell = containers.Map('KeyType','char', 'ValueType','any');
key_converter = @(tup) mat2str(tup);
sp_cell(key_converter([4 1])) = 'bar'

作为 unicode 字符串的元组

来自this answer:如果每个索引小于等于65535,则可以直接将元组转换为字符串。

key_converter = @(tup) char(tup);

散列

来自this answer:您可以将元组散列成一个字符串。

md = java.security.MessageDigest.getInstance('MD5');
key_converter = @(tup) char(md.digest(tup));

这里的缺点是您不能将映射键转换回元组。

稀疏查找表

来自@SamRobert 的评论:您可以将稀疏索引数组创建为一维元胞数组。这是一个简单粗暴的类模型:

classdef SparseCellArray
    properties (Access=protected)
        lookup
        contents
    end
    methods
        function self = SparseCellArray(m,n)
            % Constructor; takes array dimensions as [#rows, #cols]
            self.lookup = sparse(m,n);
            self.contents = {};
        end
        function B = subsref(self, S)
            % Overload matrix-style indexing
            assert(isscalar(S) && strcmp(S.type,'()'));
            idx = self.lookup(S.subs{1}, S.subs{2});
            assert(idx ~= 0, 'Index not found');
            B = self.contents{idx};
        end
        function newobj = subsasgn(self, S, B)
            % Overload matrix-style indexing 
            assert(isscalar(S) && strcmp(S.type,'()'));
            idx = self.lookup(S.subs{1}, S.subs{2});
            newobj = self;
            if (idx == 0)
                idx = length(self.contents) + 1;
                newobj.lookup(S.subs{1}, S.subs{2}) = idx;
            end
            newobj.contents{idx} = B;
        end
    end
end

而用法如下:

sp_cell = SparseCellArray(2000,100);
sp_cell(4,1) = 'foo';

缺点是它只接受二维数组(因为sparse 只产生二维数组)。另请注意,这些解决方案中的任何一个都可以包装在这样的类中。

【讨论】:

  • 这个答案的语气让我很困惑,读起来就像你忘记登录备用帐户来发布答案。
  • 如何编辑它以减少混乱?另外,回答你自己的问题是不是有礼貌?我不知道我需要一个备用帐户才能执行此操作。
  • Self-answers are explicitly encouraged。这个答案的主要问题有点奇怪,听起来你正试图从另一个帐户与自己交谈。
猜你喜欢
  • 2016-05-16
  • 1970-01-01
  • 2016-06-27
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
相关资源
最近更新 更多