File Exchange

image thumbnail

Natural-Order Row Sort

version 2.1.0 (13.9 KB) by Stephen Cobeldick
Natural-order row sort of a cell array of strings, with customizable numeric format.

15 Downloads

Updated 26 Sep 2019

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

To sort filenames or filepaths use NATSORTFILES:
http://www.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort
To sort all of the strings in a cell array use NATSORT:
http://www.mathworks.com/matlabcentral/fileexchange/34464-customizable-natural-order-sort

### Summary ###

Alphanumeric sort of the rows of a cell array of strings (1xN char). Similar to MATLAB's SORTROWS function, but takes into account the values of any numeric substrings occurring within the strings. Compare for example:

>> X = {'x2','10';'x10','0';'x1','0';'x2','2'};
>> sortrows(X) % Wrong numeric order
ans =
'x1' '0'
'x10' '0'
'x2' '10'
'x2' '2'
>> natsortrows(X) % Correct numeric order
ans =
'x1' '0'
'x2' '2'
'x2' '10'
'x10' '0'

By default NATSORTROWS interprets all consecutive digits as integer numbers, the number substring recognition can be specified using a regular expression: see NATSORT for details.

### File Dependency ###

The natural-order sort is provided by the function NATSORT (File Exchange 34464). All of NATSORT's optional inputs are supported by NATSORTROWS.

### Examples ###

>> A = {'B','2','X';'A','100','X';'B','10','X';'A','2','Y';'A','20','X'};
>> sortrows(A) % wrong numeric order:
ans =
'A' '100' 'X'
'A' '2' 'Y'
'A' '20' 'X'
'B' '10' 'X'
'B' '2' 'X'
>> natsortrows(A)
ans =
'A' '2' 'Y'
'A' '20' 'X'
'A' '100' 'X'
'B' '2' 'X'
'B' '10' 'X'
>> natsortrows(A,[],'descend')
ans =
'B' '10' 'X'
'B' '2' 'X'
'A' '100' 'X'
'A' '20' 'X'
'A' '2' 'Y'

>> sortrows(A,[2,-3]) % Wrong numeric order:
ans =
'B' '10' 'X'
'A' '100' 'X'
'A' '2' 'Y'
'B' '2' 'X'
'A' '20' 'X'
>> natsortrows(A,[],[2,-3])
ans =
'A' '2' 'Y'
'B' '2' 'X'
'B' '10' 'X'
'A' '20' 'X'
'A' '100' 'X'

>> B = {'ABCD';'3e45';'67.8';'+Inf';'-12';'+9';'NaN'};
>> sortrows(B) % wrong numeric order:
ans =
'+9'
'+Inf'
'-12'
'3e45'
'67.8'
'ABCD'
'NaN'
>> natsortrows(B,'[-+]?(NaN|Inf|\d+\.?\d*(E[-+]?\d+)?)')
ans =
'-12'
'+9'
'67.8'
'3e45'
'+Inf'
'NaN'
'ABCD'

Cite As

Stephen Cobeldick (2020). Natural-Order Row Sort (https://www.mathworks.com/matlabcentral/fileexchange/47433-natural-order-row-sort), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (6)

@Brian Oisted: converting perfectly good numeric data to CHAR is unlikely to be a good approach, and as such NATSORTROWS is not the right tool for that task. Most likely you should use NATSORTFILES just on the filenames (not on the entire cell array).

For example, where C is your cell array (the first column contains the filenames):

[~,idx] = natsortfiles(C(:,1));
C = C(idx,:);

Windows does not document the order that it displays filenames in, so reproducing the Windows order is not a trivial task.

Hi Stephen,
Thank you for writing this function, it really helps!
I am attempting to use the natsortrows function to sort a cell array where the first column is a series of file names and the next is the associated imported data. The data is in a 17x1 cell array, each cell containing a 1024x2 double of numbers. It would be great to sort these files 'naturally', as they show up in the Windows directory, but I'm unsure if the 17 1024x2 doubles need to be converted to character arrays, or if there is another workaround. Are you aware of any such workarounds, or methods of cell array (containing doubles) to character array conversions?

Siwaphon

thank you very much, It's helpful

This is brilliant!
Thank you!

Matt H

Thank you very much for this, it saved me a lot of time.

FYI at first I ran into some trouble with natsortrows saying my array must be a cell array of strings, then I tried sortrows which cleared things up by saying some cells in X contain non-scalar values. I had some empty cells left over in my array after running textscan. I was able to get it working using the following if it helps anyone else:

isArrayEmpty = cellfun('isempty',cellArray);
cellArray(isArrayEmpty) = {''};
cellArray = natsortrows(cellArray);

Thanks again

Updates

2.1.0

* Fix handling of char<num.

2.0.0

* NATSORT total rewrite: faster and less memory.
* Remove second input COL, is now supplied as optional argument.
* Improve HTML documentation.
* Include testcases.

1.6.0.0

* Add (very useful) debugging output argument.

1.5.0.0

* Improve blurb and HTML.

1.5.0.0

* Minor help edit

1.5.0.0

* Add HTML documentation.

1.5.0.0

* Improve input checking.
* include NATSORT function.

1.4.0.0

* Fix missing image.

1.4.0.0

* Include screenshot.

1.4.0.0

* Clearer description of file dependency.

1.3.0.0

* Improve function description.
* Better examples.

1.2.0.0

- Update documentation only, improve examples.

1.1.0.0

- Complete acknowledgements.

MATLAB Release Compatibility
Created with R2010b
Compatible with any release
Platform Compatibility
Windows macOS Linux