Merging multiple dictionaries with dictionaries

Related to this question, how can one merge two dictionaries that have dictionaries as the keys and values?
A = dictionary(dictionary(["key1"], {1}), dictionary(["key2"], {2}));
A(dictionary(["key3"], {3})) = dictionary(["key4"], {4})
A = dictionary (dictionary --> dictionary) with 2 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry
B = dictionary(dictionary(["key5"], {5}), dictionary(["key6"], {6}));
B(dictionary(["key7"], {7})) = dictionary(["key8"], {8})
B = dictionary (dictionary --> dictionary) with 2 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry
C = dictionary(A.keys, A.values)
Error using dictionary/keys
Unable to combine keys of type 'dictionary'. Specify the format option as "cell".
C(B.keys) = B.values

 Respuesta aceptada

A = dictionary(dictionary(["key1"], {1}), dictionary(["key2"], {2}));
A(dictionary(["key3"], {3})) = dictionary(["key4"], {4});
B = dictionary(dictionary(["key5"], {5}), dictionary(["key6"], {6}));
B(dictionary(["key7"], {7})) = dictionary(["key8"], {8});
kv = [keys(A, "cell")', keys(B, "cell")';
values(A, "cell")', values(B, "cell")'];
C=dictionary(kv{:})
C = dictionary (dictionary --> dictionary) with 4 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry

3 comentarios

James
James el 12 de Jul. de 2025
Thanks, better than loops.
Matt J
Matt J el 12 de Jul. de 2025
Editada: Matt J el 12 de Jul. de 2025
But understand that if you now want to loop over the entries of C, you will need an array of its keys. Because the keys are dictionaries, the array will have to be in cell form:
k=[keys(A, "cell"); keys(B, "cell")];
v=[values(A, "cell"); values(B, "cell")];
%% noncell key/values
kv=[k';v'];
C=dictionary(kv{:})
C = dictionary (dictionary --> dictionary) with 4 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry
for i=1:numel(k)
d=C(k{i})
end
d = dictionary (string --> cell) with 1 entry: "key2" --> {[2]} d = dictionary (string --> cell) with 1 entry: "key4" --> {[4]} d = dictionary (string --> cell) with 1 entry: "key6" --> {[6]} d = dictionary (string --> cell) with 1 entry: "key8" --> {[8]}
But you could have implemented the same loop, with less code, by accepting cell-valued dictionary entries:
%% cell key/values
C=dictionary(k,v)
C = dictionary (cell --> cell) with 4 entries: {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]}
for i=1:numel(k)
d=C{k(i)}
end
d = dictionary (string --> cell) with 1 entry: "key2" --> {[2]} d = dictionary (string --> cell) with 1 entry: "key4" --> {[4]} d = dictionary (string --> cell) with 1 entry: "key6" --> {[6]} d = dictionary (string --> cell) with 1 entry: "key8" --> {[8]}
James
James el 12 de Jul. de 2025
Thanks for explaining

Iniciar sesión para comentar.

Más respuestas (2)

f=@(i) {dictionary(["key"+i], {i})}
f = function_handle with value:
@(i){dictionary(["key"+i],{i})}
A = dictionary(f(1), f(2));
A(f(3)) = f(4)
A = dictionary (cell --> cell) with 2 entries: {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]}
B = dictionary(f(5), f(6));
B(f(7)) = f(8)
B = dictionary (cell --> cell) with 2 entries: {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]}
C = dictionary(A.keys, A.values)
C = dictionary (cell --> cell) with 2 entries: {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]}
C(B.keys) = B.values
C = dictionary (cell --> cell) with 4 entries: {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]}

12 comentarios

James
James el 12 de Jul. de 2025
Editada: James el 12 de Jul. de 2025
Thanks. These dictionaries, however, are not of the same type as my example. They are cell type: 'dictionary (cell --> cell)' not 'dictionary (dictionary --> dictionary)'.
Matt J
Matt J el 12 de Jul. de 2025
Correct. That is the form they must be in to be valid as keys/values.
James
James el 12 de Jul. de 2025
Editada: James el 12 de Jul. de 2025
Why? dictionary --> dictionary works fine in my example as individual dictionaries I just can't merge them without a loop, which I should have mentioned in the question, apologies.
Matt J
Matt J el 12 de Jul. de 2025
Editada: Matt J el 12 de Jul. de 2025
When you call the keys() or values() command, the entries are concatenated together to form an array, e.g,
d=dictionary(1,2);
d(3)=4;
k=d.keys,
k = 2×1
1 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
But it is not possible to concatentate dictionaries together. They can only exist as scalars.
Why does it bother you to wrap the dictionaries in cells?
James
James el 12 de Jul. de 2025
Editada: James el 12 de Jul. de 2025
Oh I see, so my best bet is a loop to individually add entries from one dictionary to another? I do not want them wrapped in cells just so I don't have to dereference (not sure that is the appropriate word in this context) the cell everytime I access the dictionaries.
Matt J
Matt J el 12 de Jul. de 2025
Editada: Matt J el 12 de Jul. de 2025
I don't have to dereference (not sure that is the appropriate word in this context) the cell everytime I access the dicionaries.
You don't have to:
f=@(i) dictionary(["key"+i], {i});
k=arrayfun(f,1:4,'uni',0);
v=arrayfun(f,5:8,'uni',0);
C=dictionary(k, v)
C = dictionary (cell --> cell) with 4 entries: {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]} {[dictionary (string --> cell) with 1 entry]} --> {[dictionary (string --> cell) with 1 entry]}
C{k(1)}
ans = dictionary (string --> cell) with 1 entry: "key5" --> {[5]}
f=@(i) dictionary(["key"+i], {i});
k=arrayfun(f,1:4,'uni',0);
v=arrayfun(f,5:8,'uni',0);
C=dictionary(k, v);
I would like to be able to do the following, but I can't if it is a cell type:
C{"key5"}
Error using {}
Unable to use 'string' as key for dictionary with 'cell' key type.

Caused by:
Error using cell
Conversion to cell from string is not possible.
Matt J
Matt J el 12 de Jul. de 2025
That breaks the premise of your question. In the question, the keys of C were themselves dictionaries. Now, you say you want the keys of C to be the "subkeys" of A and B? And what about the values?
Matt J
Matt J el 12 de Jul. de 2025
Editada: Matt J el 12 de Jul. de 2025
Maybe this is what you want?
f=@(i) dictionary(["key"+i], {i});
k=arrayfun(f,1:4,'uni',0);
v=arrayfun(f,5:8,'uni',0);
ksub=cell2mat( cellfun(@(c)c.keys,k,'uni',0) );
vsub=cell2mat( cellfun(@(c)c.keys,v,'uni',0) );
C=dictionary(ksub,vsub),
C = dictionary (string --> string) with 4 entries: "key1" --> "key5" "key2" --> "key6" "key3" --> "key7" "key4" --> "key8"
C("key2")
ans = "key6"
James
James el 12 de Jul. de 2025
Editada: James el 12 de Jul. de 2025
You are right, my mistake. I want to be able to access C with the dictionary itself, not a cell containing the dictionary.
Matt J
Matt J el 12 de Jul. de 2025
Editada: Matt J el 12 de Jul. de 2025
Maybe I don't have a necessary understanding of where the original dictionaries are coming from. Even before A, B are created, you apparently have a collection of multiple dictionaries from which A and B will be built. How are you holding this collection together?
It has to be with a cell array, becacuse again, dictionaries cannot be concatenated by themselves.There is no other way to maintain an array of dictionaries. And if the key/value dictionaries are already in cell form, why not continue to use them in that form?
James
James el 12 de Jul. de 2025
You gave me a lot to think about. I'm going to rework my dictionaries, however, to answer my question I posted a solution with a loop. Probably not optimal but it maintains the structure without the use of cell arrays.

Iniciar sesión para comentar.

A = dictionary(dictionary(["key1"], {1}), dictionary(["key2"], {2}));
A(dictionary(["key3"], {3})) = dictionary(["key4"], {4})
A = dictionary (dictionary --> dictionary) with 2 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry
B = dictionary(dictionary(["key5"], {5}), dictionary(["key6"], {6}));
B(dictionary(["key7"], {7})) = dictionary(["key8"], {8})
B = dictionary (dictionary --> dictionary) with 2 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry
C = dictionary;
k = keys(A, "cell");
for i = 1:length(k)
C = insert(C, cell2mat(k(i)), A(cell2mat(k(i))));
end
k = keys(B, "cell");
for i = 1:length(k)
C = insert(C, cell2mat(k(i)), B(cell2mat(k(i))));
end
C
C = dictionary (dictionary --> dictionary) with 4 entries: dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry dictionary (string --> cell) with 1 entry --> dictionary (string --> cell) with 1 entry

Categorías

Productos

Versión

R2025a

Etiquetas

Preguntada:

el 12 de Jul. de 2025

Comentada:

el 12 de Jul. de 2025

Community Treasure Hunt

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

Start Hunting!

Translated by