table2stru​ct(struct2​table(s)) does not return s when some fields are cell arrays with a single element

7 visualizzazioni (ultimi 30 giorni)
My actual goal is to sort a struct array by multiple fields. I have working code that looks roughly like this:
% We use stable sort calls in reverse priority order
[~, i_field3] = sort({my_struct.field3});
my_struct = my_struct(i_field3);
[~, i_field2] = sort([my_struct.field2]);
my_struct = my_struct(i_field2);
[~, i_field1] = sort([my_struct.field1]);
my_struct = my_struct(i_field1); % This is highest priority
I would like to follow the answer here, which vastly improves readability and maintainability:
T = struct2table(my_struct);
sortedT = sortrows(T, {'field1', 'field2', 'field3'});
my_struct = table2struct(sortedT);
However, the particular struct array I'm sorting has fields that are cell arrays, but often with a single element. Unfortunately, the new code doesn't preserve the cell array, and returns that single element only. A short way to reproduce/illustrate the problem would be this:
good_example = struct('field1', {{'abc', 'def'}}) % field1: {'abc' 'def'}
good_T = struct2table(good_example)
good_struct = table2struct(good_T) % field1: {'abc' 'def'}
bad_example = struct('field1', {{'abc'}}) % field1: {'abc'}
bad_T = struct2table(bad_example)
bad_struct = table2struct(bad_T) % field1: 'abc'
I want bad_struct to be identical to bad_example just like how good_struct is identical to good_example.
Obviously I could check for this situation and correct things, but that negates any readability/maintainability from using tables to do the sort.
Is there a way to guarantee that table2struct(struct2table(my_struct)) returns an identical struct array? Alternatively, is there a way to sort struct arrays that is better than my original code?

Risposta accettata

Stephen23
Stephen23 il 2 Mag 2023
"Is there a way to guarantee that table2struct(struct2table(my_struct)) returns an identical struct array?"
No.
"Alternatively, is there a way to sort struct arrays that is better than my original code?"
Perhaps a simple loop:
C = {'field1', 'field2', 'field3'};
X = 1:numel(S);
for k = numel(C):-1:1
[~,X] = sort({S.(C{k})});
S = S(X);
end
  1 Commento
Steve
Steve il 2 Mag 2023
OK. Glad I'm not missing anything built-in.
I like your simple loop. If I wrap that in a function it's even more readable than sortrows.
Thanks!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Structures in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by