How can I sort a string both alphabetically and numerically?

230 visualizaciones (últimos 30 días)
Caleb
Caleb el 17 de Jul. de 2012
Respondida: Stephen23 el 27 de Abr. de 2023
I'm using a list box that displays the names of the shapes I am storing in a shapefile. I'm using the sort function to list them alphabetically. This works great, but when I get to something above 9 it doesn't work quite the way I want it to. For example, my list box looks something like this:
Circle 1
Circle 10
Circle 11
Circle 12
Circle 13
Circle 2
Circle 3
Circle 4
Circle 5
Circle 6
Circle 7
Circle 8
Circle 9
Ellipse 1
Ellipse 2
Rectangle 1
.
.
.
I'd like some way to make it so that the Circles above 9 follow after the 9 instead of the 1.
  2 comentarios
Oleg Komarov
Oleg Komarov el 17 de Jul. de 2012
One general approach is to pad with zeros:
Circle 01
Circle 02
...
Circle 10
Now if you have hundreds, then
Circle 001
...
Jan
Jan el 17 de Jul. de 2012
Oleg, that's true. The leading zeros let the numerical order be the same as the alphabetical order.

Iniciar sesión para comentar.

Respuesta aceptada

Teja Muppirala
Teja Muppirala el 17 de Jul. de 2012
Very ugly, but works:
UnsortedText = {'BBB 1'; 'AAA 10'; 'AAA 9'; 'AAA 1'; 'BBB 2'; 'BBB 19'; 'BBB 9'; 'CCC 0'; 'CCC 9' ;'CCC 80'; 'CCC 7'};
R = cell2mat(regexp(UnsortedText ,'(?<Name>\D+)(?<Nums>\d+)','names'));
tmp = sortrows([{R.Name}' num2cell(cellfun(@(x)str2double(x),{R.Nums}'))]);
SortedText = strcat(tmp(:,1) ,cellfun(@(x) num2str(x), tmp(:,2),'unif',0))
There's got to be a simpler way to do this...

Más respuestas (4)

Ryan
Ryan el 17 de Jul. de 2012
FEX Submission "ASORT: A Pedestrian Alphanumeric String Sorter" works somewhat. I was able to sort something such as:
A = {'A 1', 'A 9', 'A 10', 'A 5'}; % In the order you asked for
But something such as:
A = {'A 1', 'B 10', 'A 4', 'B 2'};
Resulted in:
ans = A 1, B 2, A 4, B 10
There may be a better alphanumeric string sorter in the FEX that I missed in my quick search and that particular submission has some additional settings. You could sort each shape individually then concatenate back into one array if this function ends up as your best option.

Azzi Abdelmalek
Azzi Abdelmalek el 17 de Jul. de 2012
Editada: Azzi Abdelmalek el 17 de Jul. de 2012
list=strvcat('cir 1','cir 2','cir 10','cir 11',...
'cir 12','d 1','d 2','d 10','d 11','d 12','ee 15','dhgt 9','azs 45')
[n,m]=size(list);list1=[];list2=[];listn=[];
for k=1:n;
index = find(isstrprop(list(k,:), 'digit'), 1)
list1=strvcat(list1,list(k,1:index-1));
list2=strvcat(list2,list(k,index:end));
listn=[listn;str2num(list(k,index:end))];
end
list1c=cellstr(list1);
list2c=cellstr(list2);
listc=sortrows([list1c list2c])
listc1=listc(:,1);
list2n=str2num(char(listc(:,2)))
result1=[];k=1;result2=[];
while k<=n
ind=strmatch(listc1(k),listc1);
n1=min(ind);n2=max(ind);
result1=[result1 ;listc1(n1:n2) ]
result2=[result2; cellstr(num2str(sort(list2n(n1:n2))))]
k=k+length(ind)
end
res1=char(result1);res2=char(result2);res=[];
for k=1:n
res=strvcat(res,[strtrim(res1(k,:)) ' ' strtrim(res2(k,:))] )
end
%the result is en res variable

Marvin Seifert
Marvin Seifert el 22 de Abr. de 2020
Its an old question but still maybe I found a simpler solution:
(This works only if there is only one number in the string)
Numbers = zeros(1,length(UnsortedText));
for ii = 1:length(UnsortedText)
log = isstrprop(UnsortedText{ii},'digit')
string_name = UnsortedText{ii};
%This creates a new array only containing the numbers
numbers(ii) = string(string_name(log));
end
[~, a_order] = sort(numbers);
SortedText = UnsortedText(a_order);

Stephen23
Stephen23 el 27 de Abr. de 2023
By far the simplest approach is to download the NATSORT function:
and then use it like this:
C = {'BBB 1'; 'AAA 10'; 'AAA 9'; 'AAA 1'; 'BBB 2'; 'BBB 19'; 'BBB 9'; 'CCC 0'; 'CCC 9' ;'CCC 80'; 'CCC 7'}
C = 11×1 cell array
{'BBB 1' } {'AAA 10'} {'AAA 9' } {'AAA 1' } {'BBB 2' } {'BBB 19'} {'BBB 9' } {'CCC 0' } {'CCC 9' } {'CCC 80'} {'CCC 7' }
D = natsort(C)
D = 11×1 cell array
{'AAA 1' } {'AAA 9' } {'AAA 10'} {'BBB 1' } {'BBB 2' } {'BBB 9' } {'BBB 19'} {'CCC 0' } {'CCC 7' } {'CCC 9' } {'CCC 80'}

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by