How to sort strings by lenght?

35 views (last 30 days)
rfgdrg
rfgdrg on 31 Oct 2014
Edited: per isakson on 11 Nov 2017
Hi, I want to do this:
>> A = ['adam '
'bertil'
'cesar '
'Ada '
'berit '];
>> Asort = charsort(A)
Asort =
Ada
adam
cesar
berit
bertil
I use strtrim to remove the blanks but i have no idea how i could sort mi list by lenght. Any sugestions?

Answers (5)

Farook Sadarudeen
Farook Sadarudeen on 10 Nov 2017
Edited: per isakson on 10 Nov 2017
If your list is as below:
A = {'adam'; 'bertil'; 'cesar'; 'Ada'; 'berit'};
You can sort it based on the length as below:
[~,stringLength] = sort(cellfun(@length,A),'descend');
OutputListSorted = A(stringLength);
  1 Comment
Jan
Jan on 10 Nov 2017
"stringLength" is a confusing name for a sorting index.

Sign in to comment.


Geoff Hayes
Geoff Hayes on 31 Oct 2014
Since you asked for suggestions, here is an almost solution. Rather than using a matrix of strings, convert this to a cell array, as
A = {'adam ' 'bertil' 'cesar ' 'Ada ' 'berit '};
Then in your function, charsort, remove (as you already said) the whitespace (blanks). So you have a cell array of strings, each of which you want to find the length of. You can use cellfun to apply a function to each element of your cell array. In this case, we want to apply length as
stringLengthsOfA = cellfun(@(x)length(x),A)';
which returns a column vector (I added the apostrophe so that the result of cellfun is a column (this assumes that A is a row cell array)) like
stringLengthsOfA =
4
6
5
3
5
We have the appropriate length of each string which we can now sort. But as soon as we sort this vector, we lose the original order. So just prepend a column that has the indices of each of these lengths (so the first element 4 is for row 1, the second element 6 is for row 2, etc.) as
1 4
2 6
3 5
4 3
5 5
(The above is easy to do.) Now consider using sortrows which will allow you to specify which column to sort on and preserve the relationship between elements of each row. See what happens when you sort (the above matrix) on the second column. You will get the lengths (second column) sorted in ascending order with their corresponding indices (first column). You can then use the first column to grab the (now) sorted data from A.
Try putting the above together and see what happens!

per isakson
per isakson on 10 Nov 2017
Edited: per isakson on 10 Nov 2017
Without using a cell array
>> A = ['adam '
'bertil'
'cesar '
'Ada '
'berit '];
>> len = arrayfun( @(jj) length(strtrim(A(jj,:))), [1:size(A,1)] );
>> [ ~, ix ] = sort( len );
>> A(ix,:)
ans =
Ada
adam
cesar
berit
bertil
I guess, this is faster and uses less memory than solutions based on a cell array.

Stephen23
Stephen23 on 10 Nov 2017
Edited: Stephen23 on 10 Nov 2017
Simpler:
>> [~,idx] = sortrows(A~=32);
>> A(idx,:)
ans =
Ada
adam
cesar
berit
bertil

Jan
Jan on 10 Nov 2017
Edited: Jan on 10 Nov 2017
A = ['adam '
'bertil'
'cesar '
'Ada '
'berit '];
[~, Index] = sort(cellfun('length', cellstr(A)));
Cs = C(Index);
Similar answers have been given already, but it is worth to mention, that cellfun('length') is faster than cellfun(@length) or cellfun(@(x)length(x)).
This implies, that trailing spaces do not belong to the strings. Note that CHAR matrices are a really bad method to store multiple strings. Using a cell string or a modern STRING object is much better.
  3 Comments
per isakson
per isakson on 11 Nov 2017
Edited: per isakson on 11 Nov 2017
  • Magic strings and numbers in Matlab is a good read.
  • Yes, the "padding with spaces" requires precaution.
  • column/row-major also requires precaution. To take advantage of CHAR in the work with zillions of names the characters of single names must be stored in consecutive order in memory.
  • ... but then there is no function, sortcolumns
  • btw: I finally concatenated my zillions of short strings into a long string with char(31) as separator. Now, I keep my fingers crossed.

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!