Hay algunas implementaciones de un hash o un tipo de diccionario en la Mathworks del repositorio de archivos de Exchange. Todo lo que he visto usa la sobrecarga de paréntesis para la referencia de teclas, p.MATLAB subsref: {} con el argumento de cadena falla, ¿por qué?
d = Dict;
d('foo') = 'bar';
y = d('foo');
que parece una interfaz razonable. Sería preferible, sin embargo, si usted quiere tener fácilmente los diccionarios que contienen otros diccionarios, para utilizar los apoyos {}
en lugar de paréntesis, ya que esto le permite obtener alrededor (, parece arbitraria) Limitación de la sintaxis de MATLAB que múltiples paréntesis no son permitidos, pero múltiples apoyos están permitidos, es decir
t{1}{2}{3} % is legal MATLAB
t(1)(2)(3) % is not legal MATLAB
Así que si quieres ser fácilmente capaz de diccionarios de anidación dentro de los diccionarios,
dict{'key1'}{'key2'}{'key3'}
como es un lenguaje común en Perl y es posible y con frecuencia útil en otros idiomas incluyendo Python, entonces a menos que quiera usar n-1
variables intermedias para extraer una entrada de diccionario n
capas de profundidad, esto parece una buena opción. Y parecería fácil reescribir subsref
y subsasgn
las operaciones de la clase a hacer lo mismo para {}
, ya que previamente hicieron por ()
, y todo debería funcionar.
Excepto que no hace cuando lo intento.
Aquí está mi código. (He reducido a un caso mínimo. Sin diccionario real se lleva a cabo aquí, cada objeto tiene una clave y un valor, pero esto es suficiente para demostrar el problema.)
classdef TestBraces < handle
properties
% not a full hash table implementation, obviously
key
value
end
methods(Access = public)
function val = subsref(obj, ref)
% Re-implement dot referencing for methods.
if strcmp(ref(1).type, '.')
% User trying to access a method
% Methods access
if ismember(ref(1).subs, methods(obj))
if length(ref) > 1
% Call with args
val = obj.(ref(1).subs)(ref(2).subs{:});
else
% No args
val = obj.(ref.subs);
end
return;
end
% User trying to access something else.
error(['Reference to non-existant property or method ''' ref.subs '''']);
end
switch ref.type
case '()'
error('() indexing not supported.');
case '{}'
theKey = ref.subs{1};
if isequal(obj.key, theKey)
val = obj.value;
else
error('key %s not found', theKey);
end
otherwise
error('Should never happen')
end
end
function obj = subsasgn(obj, ref, value)
%Dict/SUBSASGN Subscript assignment for Dict objects.
%
% See also: Dict
%
if ~strcmp(ref.type,'{}')
error('() and dot indexing for assignment not supported.');
end
% Vectorized calls not supported
if length(ref.subs) > 1
error('Dict only supports storing key/value pairs one at a time.');
end
theKey = ref.subs{1};
obj.key = theKey;
obj.value = value;
end % subsasgn
end
end
Usando este código, puedo asignar como se esperaba:
t = TestBraces;
t{'foo'} = 'bar'
(Y está claro que el trabajo de asignación de la salida de la pantalla por defecto para t
.) Así subsasgn
parece funcionar correctamente.
Pero no puedo recuperar el valor (subsref
no funciona):
t{'foo'}
??? Error using ==> subsref
Too many output arguments.
El mensaje de error que no tiene sentido para mí, y un punto de interrupción en la primera línea ejecutable de mi manejador subsref
no es nunca golpear, por lo que al menos superficialmente esto parece un problema de MATLAB, no un error en mi código.
Es evidente que los argumentos de cadena a ()
subíndices paréntesis están permitidos, ya que esto funciona bien si cambia el código para trabajar con ()
en lugar de {}
. (Excepto que no puede anidar las operaciones de subíndices, que es el objeto del ejercicio).
O bien información sobre lo que estoy haciendo mal en mi código, cualquier limitación que haga que lo que estoy haciendo sea inviable o alternativa las implementaciones de diccionarios anidados serían apreciadas.
Genial, eso funciona. Sí, me gustaría saber la respuesta larga. – jmhl
Y gracias por la respuesta larga. Supuse que era algo así después de su primera respuesta, y esto lo aclara. Genial, gracias de nuevo. – jmhl
Desde R2015b, en su lugar, debe sobrecargar la función 'numArgumentsFromSubscript'; consulte las respuestas a http://stackoverflow.com/questions/8713730/matlab-subsref-with-string-argument-fails-why y la página de Mathworks https: // www. mathworks.com/help/matlab/matlab_oop/overloading-numel-subsref-and-subsasgn.html. – nekomatic