我想创建一个使用元组(例如containers.Map
)的[4,1]
对象作为密钥。但是,这不是有效的密钥类型。如何将其转换为有效的密钥类型?
我的最终目标是拥有像稀疏单元格数组的东西,我可以像矩阵一样索引但存储任意对象。
答案 0 :(得分:2)
我收到很多答案作为评论,所以对于后代(以及我自己的理智),我将这些作为实际答案写出来。
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'
从this answer开始:如果每个索引小于或等于65535,则可以直接将元组转换为字符串。
key_converter = @(tup) char(tup);
从this answer开始:您可以将元组散列为字符串。
md = java.security.MessageDigest.getInstance('MD5');
key_converter = @(tup) char(md.digest(tup));
这方面的缺点是你无法将地图密钥转换回元组。
来自@ SamRobert的评论:您可以在1-D单元阵列中创建稀疏的索引数组。这是一个快速而又脏的类的模型:
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
只生成二维数组)。另请注意,这些解决方案中的任何一个都可以包含在这样的类中。