{"id":217,"date":"2010-02-04T21:13:42","date_gmt":"2010-02-04T21:13:42","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2010\/02\/04\/constrained-sorting-of-array\/"},"modified":"2018-01-08T16:21:08","modified_gmt":"2018-01-08T21:21:08","slug":"constrained-sorting-of-array","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2010\/02\/04\/constrained-sorting-of-array\/","title":{"rendered":"Constrained Sorting of Arrays"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>In a variety of applications, customers have <a>requested<\/a> a way to sort arrays subject to some constraints.  One use case is when a row in an array represents a data record.  Clearly,\r\n         to sensibly sort data of this kind, you need to keep each row in tact.  The <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/sort.html\"><tt>sort<\/tt><\/a> function in MATLAB gives you one tool, the permutations, as the second output so you can do secondary array manipulations\r\n         with it.  With character arrays and cell arrays of strings, it made sense to do a lexical sort, which you can do with the\r\n         function <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/sortrows.html\"><tt>sortrows<\/tt><\/a>.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Regular Sorting<\/a><\/li>\r\n         <li><a href=\"#3\">Sort by a Particular Column<\/a><\/li>\r\n         <li><a href=\"#7\">Sort with Secondary Sort<\/a><\/li>\r\n         <li><a href=\"#8\">Sorting Strings<\/a><\/li>\r\n         <li><a href=\"#9\">Sorting a 2-D Array of Strings<\/a><\/li>\r\n         <li><a href=\"#11\">Assorted Sorting?<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Regular Sorting<a name=\"1\"><\/a><\/h3>\r\n   <p>Suppose you have a numeric array <tt>A<\/tt> and want to sort the vytalues in each column.  All you have to do is apply the functionjj <tt>sort<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A = [1 200 300;\r\n2 200 200;\r\n3 100 100;];\r\nsort(A)<\/pre><pre style=\"font-style:oblique\">ans =\r\n     1   100   100\r\n     2   200   200\r\n     3   200   300\r\n<\/pre><p>To generate the permutations used in the sorting, use a second output.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[~, ind] = sort(A);<\/pre><h3>Sort by a Particular Column<a name=\"3\"><\/a><\/h3>\r\n   <p>I can also choose to sort all of <tt>A<\/tt> by a particular column.  First sort that column, and then use those indices to sort the entire array.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[~, index2] = sort(A(:,2));\r\nAsort2 = A(index2,:)<\/pre><pre style=\"font-style:oblique\">Asort2 =\r\n     3   100   100\r\n     1   200   300\r\n     2   200   200\r\n<\/pre><p>I can reorder another matrix <tt>B<\/tt> according to the sort order for column 2 generated by sorting <tt>A<\/tt>.  You might want to do something akin to this if you reorder an array of eigenvalues and want to reorder the associated eigenvectors.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">B = reshape(1:9,3,3)\r\nB(index2,:)<\/pre><pre style=\"font-style:oblique\">B =\r\n     1     4     7\r\n     2     5     8\r\n     3     6     9\r\nans =\r\n     3     6     9\r\n     1     4     7\r\n     2     5     8\r\n<\/pre><p>Use <tt>sortrows<\/tt> for an easier way to keep row data together upon sorting. I can do so while choosing which column to sort by.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">Asortrows2 = sortrows(A,2)<\/pre><pre style=\"font-style:oblique\">Asortrows2 =\r\n     3   100   100\r\n     1   200   300\r\n     2   200   200\r\n<\/pre><p>This is the same result as that achieved earlier with sort and indexing combined.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">isequal(Asort2, Asortrows2)<\/pre><pre style=\"font-style:oblique\">ans =\r\n     1\r\n<\/pre><h3>Sort with Secondary Sort<a name=\"7\"><\/a><\/h3>\r\n   <p>Suppose  I want to keep rows in tact, and sort an array according to values in a particular column, and break ties in sorting\r\n      according to another column.  I can do that with <tt>sortrows<\/tt> as well.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">sortrows(A, [2, 1])<\/pre><pre style=\"font-style:oblique\">ans =\r\n     3   100   100\r\n     1   200   300\r\n     2   200   200\r\n<\/pre><h3>Sorting Strings<a name=\"8\"><\/a><\/h3>\r\n   <p>I can use <tt>sortrows<\/tt> to sort a cell array of strings alphabetically.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">str = {<span style=\"color: #A020F0\">'one'<\/span>; <span style=\"color: #A020F0\">'two'<\/span>; <span style=\"color: #A020F0\">'three'<\/span>; <span style=\"color: #A020F0\">'four'<\/span>; <span style=\"color: #A020F0\">'five'<\/span>}\r\nstrsort = sortrows(str)<\/pre><pre style=\"font-style:oblique\">str = \r\n    'one'\r\n    'two'\r\n    'three'\r\n    'four'\r\n    'five'\r\nstrsort = \r\n    'five'\r\n    'four'\r\n    'one'\r\n    'three'\r\n    'two'\r\n<\/pre><h3>Sorting a 2-D Array of Strings<a name=\"9\"><\/a><\/h3>\r\n   <p>Suppose I have a 2-D cell array of strings now.  I can sort each column of strings, independent of each other (like <tt>sort<\/tt> does for numeric values), getting the sorting permutation in a second output if I wish.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">xt = str';\r\nxta  = [xt; xt(randperm(5)); xt(randperm(5))]\r\n[xtasort,indexxta] = sortrows(xta)<\/pre><pre style=\"font-style:oblique\">xta = \r\n    'one'     'two'      'three'    'four'     'five'\r\n    'five'    'four'     'one'      'three'    'two' \r\n    'five'    'three'    'one'      'four'     'two' \r\nxtasort = \r\n    'five'    'four'     'one'      'three'    'two' \r\n    'five'    'three'    'one'      'four'     'two' \r\n    'one'     'two'      'three'    'four'     'five'\r\nindexxta =\r\n     2\r\n     3\r\n     1\r\n<\/pre><p>And I can sort the string rows according to contents of specific columns.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[xta23,indexxta23] = sortrows(xta,[2,3])<\/pre><pre style=\"font-style:oblique\">xta23 = \r\n    'five'    'four'     'one'      'three'    'two' \r\n    'five'    'three'    'one'      'four'     'two' \r\n    'one'     'two'      'three'    'four'     'five'\r\nindexxta23 =\r\n     2\r\n     3\r\n     1\r\n<\/pre><h3>Assorted Sorting?<a name=\"11\"><\/a><\/h3>\r\n   <p>In addition to what I've mentioned, you can choose to sort, via the function <tt>sort<\/tt>, in descending order in addition to ascending.  What sort of sorting do you need to do with your data and algorithms?  Do\r\n      you use lexical sorting?  How about dependent sorts, e.g., according to some specific columns, or according to the sort order\r\n      of an array of data? Let me know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=217#respond\">here<\/a>.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_7a65e68a3ee5466aa927fdaa9145e4f6() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='7a65e68a3ee5466aa927fdaa9145e4f6 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 7a65e68a3ee5466aa927fdaa9145e4f6';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Loren Shure';\r\n        copyright = 'Copyright 2010 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n      \r\n-->\r\n<\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_7a65e68a3ee5466aa927fdaa9145e4f6()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.9<br><\/p>\r\n<\/div>\r\n<!--\r\n7a65e68a3ee5466aa927fdaa9145e4f6 ##### SOURCE BEGIN #####\r\n%% Constrained Sorting of Arrays\r\n% In a variety of applications, customers have \r\n% <http:\/\/search_results?search_string=sortrows requested>\r\n% a way to sort arrays subject to some constraints.  One use case is when a\r\n% row in an array represents a data record.  Clearly, to sensibly sort data\r\n% of this kind, you need to keep each row in tact.  The\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/sort.html |sort|>\r\n% function in MATLAB gives you one tool, the permutations, as the second\r\n% output so you can do secondary array manipulations with it.  With\r\n% character arrays and cell arrays of strings, it made sense to do a\r\n% lexical sort, which you can do with the function\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/sortrows.html |sortrows|>.\r\n%% Regular Sorting\r\n% Suppose you have a numeric array |A| and want to sort the vytalues in each\r\n% column.  All you have to do is apply the functionjj |sort|.\r\nA = [1 200 300;\r\n2 200 200;\r\n3 100 100;];\r\nsort(A)\r\n%%\r\n% To generate the permutations used in the sorting, use a second output.\r\n[~, ind] = sort(A);\r\n\r\n%% Sort by a Particular Column\r\n% I can also choose to sort all of |A| by a particular column.  First sort\r\n% that column, and then use those indices to sort the entire array.\r\n[~, index2] = sort(A(:,2));\r\nAsort2 = A(index2,:)\r\n%%\r\n% I can reorder another matrix |B| according to the sort order for column 2\r\n% generated by sorting |A|.  You might want to do something akin to this if\r\n% you reorder an array of eigenvalues and want to reorder the associated\r\n% eigenvectors.\r\nB = reshape(1:9,3,3)\r\nB(index2,:)\r\n%% \r\n% Use |sortrows| for an easier way to keep row data together upon sorting.\r\n% I can do so while choosing which column to sort by.\r\nAsortrows2 = sortrows(A,2)\r\n%%\r\n% This is the same result as that achieved earlier with sort and indexing\r\n% combined.\r\nisequal(Asort2, Asortrows2)\r\n%% Sort with Secondary Sort\r\n% Suppose  I want to keep rows in tact, and sort an array according to\r\n% values in a particular column, and break ties in sorting according to\r\n% another column.  I can do that with |sortrows| as well.\r\nsortrows(A, [2, 1])\r\n%% Sorting Strings\r\n% I can use |sortrows| to sort a cell array of strings alphabetically.\r\nstr = {'one'; 'two'; 'three'; 'four'; 'five'}\r\nstrsort = sortrows(str)\r\n%% Sorting a 2-D Array of Strings\r\n% Suppose I have a 2-D cell array of strings now.  I can sort each column\r\n% of strings, independent of each other (like |sort| does for numeric\r\n% values), getting the sorting permutation in a second output if I wish.\r\nxt = str';\r\nxta  = [xt; xt(randperm(5)); xt(randperm(5))]\r\n[xtasort,indexxta] = sortrows(xta)\r\n%% \r\n% And I can sort the string rows according to contents of specific columns.\r\n[xta23,indexxta23] = sortrows(xta,[2,3])\r\n%% Assorted Sorting?\r\n% In addition to what I've mentioned, you can choose to sort, via the\r\n% function |sort|, in descending order in addition to ascending.  What sort\r\n% of sorting do you need to do with your data and algorithms?  Do you use\r\n% lexical sorting?  How about dependent sorts, e.g., according to some\r\n% specific columns, or according to the sort order of an array of data?\r\n% Let me know <https:\/\/blogs.mathworks.com\/loren\/?p=217#respond here>.\r\n\r\n##### SOURCE END ##### 7a65e68a3ee5466aa927fdaa9145e4f6\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      In a variety of applications, customers have requested a way to sort arrays subject to some constraints.  One use case is when a row in an array represents a data record.  Clearly,\r\n    ... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2010\/02\/04\/constrained-sorting-of-array\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[15],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/217"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=217"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/217\/revisions"}],"predecessor-version":[{"id":2624,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/217\/revisions\/2624"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}