# Ordering of an array based off conditions

18 views (last 30 days)
TGB on 17 May 2023
Commented: TGB on 18 May 2023
Good evening all,
Correction: variables are cell arrays*
I am looking to arrange the following variable:
tmp = {'1e2','1h4','1t0', '3g2', '3g3', '3g4', '3q0', '3q1', '3q2'};
letter_list = {'t','q','e','g','h','i','j'}
letter_list = 1×7 cell array
{'t'} {'q'} {'e'} {'g'} {'h'} {'i'} {'j'}
I am looking to find a way to sort variable tmp to the desired array below:
desired_var = {'1t0', '1e2', '1h4', '3q2', '3q1', '3q0', '3g4', '3g3', '3g2'};
To elaborate
1. rows with 1 in the tmp(:,1) == 1 are sorted by the order of their respective 2nd column index where they appear in order of appearance to letter_list.
2. rows with columns one and two equivalent are group, such that all 3q rows are grouped and then ordered based off the third column, with the highest number first and descending
3. then to combine all 1 and 2 into one variable to produce desired_var

the cyclist on 18 May 2023
% Input data
tmp = {'1e2','1h4','1t0', '3g2', '3g3', '3g4', '3q0', '3q1', '3q2'};
letter_list = {'t','q','e','g','h','i','j'};
% Get first number (which will be sorted in ascending order)
num1 = cellfun(@(x)(str2double(x(1))),tmp)';
% Get second character, and finding sorting order according to letter_list
char2 = cellfun(@(x)(x(2)),tmp);
[~,num2] = ismember(char2',letter_list);
% Get third number (which will be sorted in descending order)
num3 = cellfun(@(x)(str2double(x(3))),tmp)';
% Get the sorting order by putting the three vectors into a matrix to sort
[~,sortingIndex] = sortrows([num1,num2,num3],[1 2 3],{'ascend','ascend','descend'});
% Apply the sorting to tmp
desired_var = tmp(sortingIndex)
desired_var = 1×9 cell array
{'1t0'} {'1e2'} {'1h4'} {'3q2'} {'3q1'} {'3q0'} {'3g4'} {'3g3'} {'3g2'}
##### 3 CommentsShow 1 older commentHide 1 older comment
Allen on 18 May 2023
Refining my previous answer with a few extra steps.
tmp = {'1e2','1h4','1t0','3g2','3g3','3g4','3q0','3q1','3q2'};
letter_list = {'t','q','e','g','h','i','j'};
tmpList = char(tmp);
C = categorical(cellstr(tmpList(:,2)),letter_list,"Ordinal",true);
T = table(tmpList(:,1),C,tmpList(:,3),tmp','VariableNames',["Col1","Col2","Col3","CharArray"]);
T = sortrows(T,["Col1","Col2","Col3"],["ascend","ascend","descend"]);
TGB on 18 May 2023
Hi Allen,

Allen on 18 May 2023
You can perform sorting to a specified order using a categorical array. To do this you will need to restructure your original variables slightly and extract the letters from your tmp variable.
I also make a couple of initial assumptions that your tmp and letter_list variables are cell-arrays (culy-brackets, {}), of character vectors, and all character vectors within a give array are the same size. I also assume that the elements in the letter_list array are already in the desired sorting order.
tmp = {'1e2','1h4','1t0','3g2','3g3','3g4','3q0','3q1','3q2'};
letter_list = {'t','q','e','g','h','i','j'};
Next, covert the tmp cell-array into a character vector array so that the second element of each character vector can be easily extracted (assuming that the second element will always be the letter).
% Convert to char array
tmpList = char(tmp);
tmpList
% tmpList =
% 9×3 char array
% '1e2'
% '1h4'
% '1t0'
% '3g2'
% '3g3'
% '3g4'
% '3q0'
% '3q1'
% '3q2'
% Extract letters from 2nd column of the char array
letters = tmpList(:,2);
letters
% letters =
% 9×1 char array
% 'e'
% 'h'
% 't'
% 'g'
% 'g'
% 'g'
% 'q'
% 'q'
% 'q'
Next, convert the extracted letters back into a cell-string and then into a categorical variable. While converting into a categorical variable you will use the pre-ordered list to set the desired order.
C = categorical(cellstr(letters),letter_list,"Ordinal",true);
Finally, create a table with columns containing the categorical and tmp array variables, and use sortrows to sort the table rows. By default tables use the first column to sort in ascending order, and in this case will be the categorical letters in the desired order.
T = table(C,tmp','VariableNames',["Category","CharArray"]);
T = sortrows(T);
T
% T =
% 9×2 table
% Category CharArray
% ________ _________
% t {'1t0'}
% q {'3q0'}
% q {'3q1'}
% q {'3q2'}
% e {'1e2'}
% g {'3g2'}
% g {'3g3'}
% g {'3g4'}
% h {'1h4'}
If you are not familiar with tables, you can call the column seperately using dot notation or by their array indices using curly brackets similarly to cell-arrays.
% Equivalent methods
T.CharArray;
T{:,2};
% You can also use the follow syntax, but this will return the answer as a
% table variable.
T(:,2);