How can I sort a string both alphabetically and numerically?
157 次查看(过去 30 天)
显示 更早的评论
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 个评论
Oleg Komarov
2012-7-17
One general approach is to pad with zeros:
Circle 01
Circle 02
...
Circle 10
Now if you have hundreds, then
Circle 001
...
Jan
2012-7-17
Oleg, that's true. The leading zeros let the numerical order be the same as the alphabetical order.
采纳的回答
Teja Muppirala
2012-7-17
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...
更多回答(4 个)
Ryan
2012-7-17
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.
0 个评论
Azzi Abdelmalek
2012-7-17
编辑:Azzi Abdelmalek
2012-7-17
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
0 个评论
Marvin Seifert
2020-4-22
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);
0 个评论
Stephen23
2023-4-27
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'}
D = natsort(C)
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!