Can a Dictionary Key be a char?

Playing with the new dictionary in 2022b and discovered that a char can't be used as the key (can use a string though)
string.empty
ans = 0×0 empty string array
dictionary(string.empty,double.empty)
ans =
dictionary (stringdouble) with no entries.
char.empty
ans = 0×0 empty char array
dictionary(char.empty,double.empty)
Error using dictionary
Dimensions of the key and value must be compatible, or the value must be scalar.

5 commentaires

Bruno Luong
Bruno Luong le 17 Sep 2022
Modifié(e) : Bruno Luong le 17 Sep 2022
char(string.empty) is equal to char(zeros(0,0,0)) and not equall to char.empty, which is char(zeros(0)).
This works
d=dictionary(char(zeros(0,0,0)),[])
d =
dictionary (stringdouble) with no entries.
This is also be accepted
d=dictionary(char(zeros(0,1,0)),[])
d =
dictionary (stringdouble) with no entries.
But (oddly to me) not this
d=dictionary(char(zeros(1,1,0)),[]) % or not this either d=dictionary(char(zeros(0,1)),[])
Error using dictionary
Dimensions of the key and value must be compatible, or the value must be scalar.
Bruno Luong
Bruno Luong le 17 Sep 2022
A dictionary that contains no more than 26 alphabet letters is pretty boring.
Paul
Paul le 18 Sep 2022
Modifié(e) : Paul le 18 Sep 2022
Except that the first two examples make a dictionary with key type string, not char. If that's what's wanted, just make the key string.empty.
In some applications, 26 keys might be sufficient, or as many ASCII chars as there may be.
A single character string can do the job as a key, but I don't see a way to enforce each string key be only a single character.
If a char key is not allowed, the dictionary doc page should say so, IMO.
Dictionaries do not accept these data types as keys or values:
  • Tables
  • Tall arrays
  • Distributed arrays
  • graph and digraph objects
"... any type that is hashable using keyHash can be used as a key."
char seems to satisfy this requirement
keyHash('c')
ans = uint64 1345289965948033828
Bruno Luong
Bruno Luong le 18 Sep 2022
Modifié(e) : Bruno Luong le 18 Sep 2022
"Except that the first two examples make a dictionary with key type string"
Does it matter for user? It is string internally only, but user can still add, inquire delete using char key with such dictionary.
TMW makes great effort to make many function works for both string and char-array. So internally of dictionaly class the constructor converts char-key to string, so the method of the class can be single branch. I state it clearly in my answer.
char array is historical data type (*) and has simplicity but lack of formal sophisticated object property as string. At your level I'm still surprise you bump into the difficulty to understand the difference between char.empty and string.empty.
(*) it hacks the second dimension to store "string" or must be contains in cell which is another top level totally different.

Connectez-vous pour commenter.

Réponses (3)

You have to put the character or character array into a cell because the keys are in a cell array. Watch:
keys = {'a'; 'b'; 'c'}
keys = 3×1 cell array
{'a'} {'b'} {'c'}
values = [1; 2; 3]; % A column vector of doubles.
d = dictionary(keys, values) % Create the dictionary.
d =
dictionary (celldouble) with 3 entries: {'a'} ⟼ 1 {'b'} ⟼ 2 {'c'} ⟼ 3
% Find value when key is 'b'
val = d({'b'}) % Pass in 'b' but put it in braces to make it a cell.
val = 2
See the FAQ for a good discussion of cell arrays: https://matlab.fandom.com/wiki/FAQ#What_is_a_cell_array?

2 commentaires

Paul
Paul le 18 Sep 2022
Modifié(e) : Paul le 18 Sep 2022
Yes, I'm aware of cell arrays. Seems kind of a pain to make each key a cell instead of a char.
Also, because each cell is a scalar, there's nothing that limits the key to be a single char, which may be desirable. Same issue if the key is a string.
d = dictionary({'a'},1)
d =
dictionary (celldouble) with 1 entry: {'a'} ⟼ 1
d({'ab'}) = 2
d =
dictionary (celldouble) with 2 entries: {'a'} ⟼ 1 {'ab'} ⟼ 2
And if a cell is the key, it basically allows anything to be a key
d({@sin}) = 3
d =
dictionary (celldouble) with 3 entries: {'a'} ⟼ 1 {'ab'} ⟼ 2 {@sin} ⟼ 3
In any case, if a char key is not allowed, dictionary should say so, IMO.
Bruno Luong
Bruno Luong le 18 Sep 2022
"n any case, if a char key is not allowed, dictionary should say so, IMO."
Not IMO, such detail make the doc filled with unteresting details.

Connectez-vous pour commenter.

Bruno Luong
Bruno Luong le 17 Sep 2022
Modifié(e) : Bruno Luong le 17 Sep 2022

0 votes

It looks to me that dictionary can accept both char array and string indisrtinctively as keys, as it convert to string internally, but one can add, inquire key in either format. >So it is justt flexible kind of interface.
d=dictionary(string.empty,[])
d('a')=pi
d("a")
d('a')
Nothing prevent you to use exclusively char array of length-1 (so a char) as key. Internally it will associate or equivalent to string array of length-1 strings.

4 commentaires

Paul
Paul le 18 Sep 2022
Modifié(e) : Paul le 18 Sep 2022
A single character string can do the job as a key, but I don't see a way to enforce each string key be only a single character.
If a char key is not allowed, the dictionary doc page should say so, IMO.
Also, this converts the char key to a string key
d = dictionary('a',1)
d =
dictionary (stringdouble) with 1 entry: "a" ⟼ 1
but this doesn't?
size(char.empty)
ans = 1×2
0 0
size(double.empty)
ans = 1×2
0 0
d = dictionary(char.empty,double.empty)
Error using dictionary
Dimensions of the key and value must be compatible, or the value must be scalar.
Also, the error message implies the dimensions of the key and value aren't compatible, but those dimensions are compatible if the key is string.empty
Bruno Luong
Bruno Luong le 18 Sep 2022
Modifié(e) : Bruno Luong le 18 Sep 2022
When enter
% d = dictionary(char.empty,double.empty)
don 't you see that there is no formal way for MATLAB to distinguish of
  • the desired type key of you command is single-char key (you want) as oppose to
  • non-single char key (== string), assumed.
So it is assumes you want to do non-single char key (second interpretation).
In this case char.empty is '' which is "" after convertion to string so it is consider char.empty as ONE instance and not 0 for value. Tat explaons the error messge yoy see.
This to matlab this is coherent, (and not your command):
clear d
d = dictionary(char.empty,1)
Don' try to over-interpret char.empty as meta data as you do, there is no such interpretation as empty set of char (string allows that not char array). It is just an array of char of length 0, which is one instance of char-array.
In any case the use case of single char is not useful. Beside the desire of being pedentic on the doc not many people would use single char as key for dictionary.
Why wouldn't there be way for Matalb to distinguish those two cases? If I configure the dictionary with a char, it means I want a char. If I configure it with a string, it means I want a string. Offhand, I don't see why TMW has to assume anything; I'm sure they had their reasons.
I have no idea whether or not a char key or char value would have been useful. Obviously, TMW decided it wouldn't be.
Would you mind expanding on this statement: "Don't try to over-interpret char.empty as meta data as you do, there is no such interpretation as empty set of char (string allows that not char array). It is just an array of char of length 0, which is one instance of char-array." I don't know what you mean by meta data in this context or "one instance."
c = char.empty;
class(c)
ans = 'char'
isempty(c)
ans = logical
1
size(c)
ans = 1×2
0 0
s = string.empty;
class(s)
ans = 'string'
isempty(s)
ans = logical
1
size(s)
ans = 1×2
0 0
Other than that c and s instances are different classes, how else are they different?
Bruno Luong
Bruno Luong le 18 Sep 2022
Modifié(e) : Bruno Luong le 18 Sep 2022
"Why wouldn't there be way for Matalb to distinguish those two cases? "
Obviousmy because they want the two types to be interchagable as much as possible, if you have followed they deveoptment of string and char. You might not be happy but it's their line of development.
Explanation of "one instance"
emptyc = char.empty
emptyc = 0×0 empty char array
stringofemptyc = string(emptyc)
stringofemptyc = ""
length(stringofemptyc)
ans = 1
So
the equivalent of emptyc in string is NOT string.empty but "". This object is one instance (scalar if you will) of class string.
There is NO strict equivalent of char-array of string.empty, or put it that way, it's NOT char.empty but
charempty = char(zeros([0 0 0]))
charempty = 0×0×0 empty char array
string(charempty)
ans = 0×0 empty string array

Connectez-vous pour commenter.

Bruno Luong
Bruno Luong le 18 Sep 2022
Modifié(e) : Bruno Luong le 18 Sep 2022
The syntax that needs to be used is
d = dictionary(char.empty(0,0,0), [])
d =
dictionary (stringdouble) with no entries.

Produits

Version

R2022b

Tags

Question posée :

le 17 Sep 2022

Modifié(e) :

le 18 Sep 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by