I have a cell array in Matlab, with each cell representing a financial transaction as a structure object (the cell array is earlier imported from a json file).
Here is an example to create a test set which replicates the features of my data, representing 4 individual transactions in this case:
transaction_1 = struct( 'created_on' , '2023-01-22' , 'amount' , 9.60 , 'merchant' , struct('name','ebay') );
transaction_2 = struct( 'created_on' , '2022-11-22' , 'amount' , 6.20 , 'merchant' , struct('name','ikea') );
transaction_3 = struct( 'created_on' , '2019-06-19' , 'amount' , 3.65 , 'merchant' , [] );
transactions = { transaction_1 ; transaction_2 ; transaction_3 };
% Add a fourth which is not "compatible" in dimension with the others
transactions{4} = struct( 'created_on' , '2019-06-19' , 'amount' , 1.25 , 'merchant' , [] , 'location' , 'London');
Each structure in the cell array contains three fields:
The third transaction does not have merchant information in the test set, so transactions{3}.merchant
returns empty, while the fourth transaction also has location data.
Now I wish to extract field values from the individual structures into separate cell arrays. The following code works correctly for the dates and amounts
created_on = cellfun(@(x) x.created_on , transactions , 'UniformOutput' , false);
amounts = cellfun(@(x) x.amount , transactions , 'UniformOutput' , false);
merchant_names = cellfun(@(x) x.merchant.name , transactions , 'UniformOutput' , false);
but fails for the merchants because the name doesn't exist in some cases. Is there a nice way to do this without resorting to a loop over all entries?
You could make a helper function to handle the different cases, then just use that in your cellfun
.
merchant_names = cellfun( @(x) structValIfExists(x.merchant, 'name'), transactions, 'uni', 0 );
% >> merchant_names = {'ebay', 'ikea', ''}
function v = structValIfExists( s, fld )
if isstruct( s ) && isfield( s, fld )
v = s.(fld);
else
v = '';
end
end