Trouble using container with cell type for key and structure array for values..

25 views (last 30 days)
Given this table,
TestTable_valid =
11×6 table
SerialNumber ACCurrentPreSyncEn ACCurrentPostSyncEn PassFail Model LCRSwept_Yes_No
____________________ __________________ ___________________ __________ _________ _______________
{'A017441206210001'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2C' } {'Yes'}
{'A017441229220004'} {'7.0A'} {'8.6A'} {'Passed'} {'VA2C' } {'Yes'}
{'A020621202230003'} {'0A' } {'7.7A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621203230003'} {'0A' } {'7.6A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621207230002'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621208230001'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621210230006'} {'1.2A'} {'0.7' } {'Failed'} {'VA2CE'} {'Yes'}
{'A020621215230003'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'}
{'A020621222230004'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'}
{'A020622108240013'} {'7.1A'} {'0A' } {'Passed'} {'VA2CE'} {'Yes'}
{'A020622109240009'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2CE'} {'Yes'}
I'm trying to create a container that uses the serial number as the key, and returns the other columns:
serials = TestTable_valid.SerialNumber
dataValues = TestTable_valid(:, 2:6)
dataStructArray = table2struct(dataValues)
% Create map: key = serial number, value = table row with C–G
lookupMap = containers.Map(serials, dataStructArray, 'UniformValues', false); % needed because data types in structure may be different.
however, I get the following error:
Error using containers.Map
Specified value type does not match the type expected for this container.
Don't know what else to try...I'm not sure cell vs. character array, vs cell array of characters, so perhaps that is the issue.....
I appreciate the help...
Jorge
  6 Comments
Walter Roberson
Walter Roberson on 7 May 2025
As of R2025a (currently pre-release), you will be able to use
dataStructArray = num2cell(dataValues,2);
to create a cell array in which each row is a cell array containing the variables.
Unfortunately in R2024b and earlier, building such a cell array is most easily done using a loop.
Jorge
Jorge on 7 May 2025
this worked....
TestTable_valid = readtable('TestTable_valid.xlsx')
TestTable_valid = 11x6 table
SerialNumber ACCurrentPreSyncEn ACCurrentPostSyncEn PassFail Model LCRSwept_Yes_No ____________________ __________________ ___________________ __________ _________ _______________ {'A017441206210001'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2C' } {'Yes'} {'A017441229220004'} {'7.0A'} {'8.6A'} {'Passed'} {'VA2C' } {'Yes'} {'A020621202230003'} {'0A' } {'7.7A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621203230003'} {'0A' } {'7.6A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621207230002'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621208230001'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621210230006'} {'1.2A'} {'0.7' } {'Failed'} {'VA2CE'} {'Yes'} {'A020621215230003'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'} {'A020621222230004'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'} {'A020622108240013'} {'7.1A'} {'0A' } {'Passed'} {'VA2CE'} {'Yes'} {'A020622109240009'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2CE'} {'Yes'}
serials = cell(TestTable_valid.SerialNumber)
serials = 11x1 cell array
{'A017441206210001'} {'A017441229220004'} {'A020621202230003'} {'A020621203230003'} {'A020621207230002'} {'A020621208230001'} {'A020621210230006'} {'A020621215230003'} {'A020621222230004'} {'A020622108240013'} {'A020622109240009'}
dataCell = table2cell(TestTable_valid(:, 2:6));
rowCells = mat2cell(dataCell, ones(size(dataCell,1),1),size(dataCell,2))
rowCells = 11x1 cell array
{1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell} {1x5 cell}
lookupMap = containers.Map(serials, rowCells)
lookupMap =
Map with properties: Count: 11 KeyType: char ValueType: any
fields = lookupMap(serials{1})
fields = 1x5 cell array
{'7.1A'} {'7.1A'} {'Passed'} {'VA2C'} {'Yes'}
fprintf('SN: %s | Pre: %s | Post: %s | Result: %s | Model: %s | LCR: %s\n', ...
serials{1}, fields{1}, fields{2}, fields{3}, fields{4}, fields
SN: A017441206210001 | Pre: 7.1A | Post: 7.1A | Result: Passed | Model: VA2C | LCR: Yes
Thank you for your help.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 7 May 2025
Moved: Walter Roberson on 7 May 2025
struct values are not permitted.
keys = 100:110;
values = struct('abc', num2cell(1:11))
values = 1x11 struct array with fields:
abc
containers.Map(keys, values)
Error using containers.Map
Specified value type does not match the type expected for this container.

More Answers (2)

Matt J
Matt J on 7 May 2025
Edited: Matt J on 7 May 2025
Perhaps use a dictionary, instead of containers.Map?
keys = compose("A0%.2d" , 1:15);
values = struct('abc', num2cell(1:15));
d=dictionary(keys, values),
d = dictionary (string --> struct) with 15 entries: "A001" --> 1x1 struct "A002" --> 1x1 struct "A003" --> 1x1 struct "A004" --> 1x1 struct "A005" --> 1x1 struct "A006" --> 1x1 struct "A007" --> 1x1 struct "A008" --> 1x1 struct "A009" --> 1x1 struct "A010" --> 1x1 struct "A011" --> 1x1 struct "A012" --> 1x1 struct "A013" --> 1x1 struct "A014" --> 1x1 struct "A015" --> 1x1 struct
d("A008")
ans = struct with fields:
abc: 8

Eric Sofen
Eric Sofen on 5 Jun 2025 at 21:26
Is there a reason you want to use a container other than table?
Are the SerialNumbers unique? If so, you can put them in the RowNames property of the table and "query" the table using subscripting:
TestTable_valid = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1833727/TestTable_valid.xlsx')
TestTable_valid = 11×6 table
SerialNumber ACCurrentPreSyncEn ACCurrentPostSyncEn PassFail Model LCRSwept_Yes_No ____________________ __________________ ___________________ __________ _________ _______________ {'A017441206210001'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2C' } {'Yes'} {'A017441229220004'} {'7.0A'} {'8.6A'} {'Passed'} {'VA2C' } {'Yes'} {'A020621202230003'} {'0A' } {'7.7A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621203230003'} {'0A' } {'7.6A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621207230002'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621208230001'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'} {'A020621210230006'} {'1.2A'} {'0.7' } {'Failed'} {'VA2CE'} {'Yes'} {'A020621215230003'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'} {'A020621222230004'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'} {'A020622108240013'} {'7.1A'} {'0A' } {'Passed'} {'VA2CE'} {'Yes'} {'A020622109240009'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2CE'} {'Yes'}
TestTable_valid.Properties.RowNames = TestTable_valid.SerialNumber;
TestTable_valid.SerialNumber = [];
TestTable_valid.Properties.DimensionNames(1) = "SerialNumber";
% get all data for one row
TestTable_valid("A020621208230001",:)
ans = 1×5 table
ACCurrentPreSyncEn ACCurrentPostSyncEn PassFail Model LCRSwept_Yes_No __________________ ___________________ __________ _________ _______________ A020621208230001 {'0A'} {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'}
% get just PassFail for one row
TestTable_valid.PassFail("A020621208230001")
ans = 1×1 cell array
{'Failed'}
% and of course, table, unlike dictionary, means that if you need to slice
% across all SerialNumbers, you still can:
TestTable_valid.Model
ans = 11×1 cell array
{'VA2C' } {'VA2C' } {'VA2CE'} {'VA2CE'} {'VA2CE'} {'VA2CE'} {'VA2CE'} {'VA2CE'} {'VA2CE'} {'VA2CE'} {'VA2CE'}
  4 Comments
Eric Sofen
Eric Sofen on 9 Jun 2025 at 14:13
@Walter Roberson, Perhaps. That's why I asked the question. You and Matt are correct that if you just need to access data by looking up the SerialNumber, the fastest thing is to use a dictionary. (And we encourage you to use dictionary rather than containers.Map. Dictionary addresses several performance and behavioral issues with containers.). Lookup performance can be particularly important when doing a fast calculation in a tight loop and dictionary probably wins there. However, as I attempted to illustrate above, if Jorge wants to do things other than look up rows, then table may still be a good option. Vectorized calculations on one variable are a lot faster and easier on the table than the dictionary of structs.
Having real-world use cases is helpful for me as I think about table performance, because there are ultimately trade-offs in performance and functionality.

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!