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

 Accepted Answer

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 Comments

Thanks, better than loops.
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]}
Thanks for explaining

Sign in to comment.

More Answers (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 Comments

James
James on 12 Jul 2025
Edited: James on 12 Jul 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)'.
Correct. That is the form they must be in to be valid as keys/values.
James
James on 12 Jul 2025
Edited: James on 12 Jul 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.
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 on 12 Jul 2025
Edited: James on 12 Jul 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.
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.
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?
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 on 12 Jul 2025
Edited: James on 12 Jul 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 on 12 Jul 2025
Edited: Matt J on 12 Jul 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?
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.

Sign in to comment.

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

Products

Release

R2025a

Tags

Asked:

on 12 Jul 2025

Commented:

on 12 Jul 2025

Community Treasure Hunt

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

Start Hunting!