459,504 Members | 1,191 Online
Need help? Post your question and get tips & solutions from a community of 459,504 IT Pros & Developers. It's quick & easy.

# sort() a string by a number within the string?

 P: n/a Hi all, I have an array of strings. For example... [0] = "entry1 first entry"; [1] = "entry2 second entry"; [2] = "entry3 third entry"; etc... How can I sort this array by the number after "entry"? David Sep 15 '05 #1
9 Replies

 P: n/a I should have stated that the array may become mixed when some processing in the script is changed. For example.. [0] = "entry1 first entry"; [1] = "entry3 third entry"; [2] = "entry2 second entry"; etc... So I need to straighten it out, sort() it, to be in numerical order by the number after the word "entry" so that the end result is like this.. [0] = "entry1 first entry"; [1] = "entry2 second entry"; [2] = "entry3 third entry"; etc... David "David" wrote in message news:sDiWe.12303\$YI6.11468@trnddc05... Hi all, I have an array of strings. For example... [0] = "entry1 first entry"; [1] = "entry2 second entry"; [2] = "entry3 third entry"; etc... How can I sort this array by the number after "entry"? David Sep 15 '05 #2

 P: n/a David wrote: I should have stated that the array may become mixed when some processing in the script is changed. For example.. [0] = "entry1 first entry"; [1] = "entry3 third entry"; [2] = "entry2 second entry"; An array object has a sort method to which you can pass your own comparison function if needed that compares what you want to compare e.g. var a = new Array(); a[0] = "entry1 first entry"; a[1] = "entry3 third entry"; a[2] = "entry2 second entry"; var result = a.join('|'); a.sort(function (el1, el2) { var pattern = /^entry(\d+)/g; var n1, n2; pattern.lastIndex = 0; var match1 = pattern.exec(el1); if (match1) { n1 = Number(match1[1]); } pattern.lastIndex = 0; var match2 = pattern.exec(el2); if (match2) { n2 = Number(match2[1]); } if (typeof n1 != 'undefined' && typeof n2 != 'undefined') { return n1 - n2; } else { // no numbers found // could throw an error return -1; } }); result += '\r\n\r\n' + a.join('|'); alert(result); Documentation is here: -- Martin Honnen http://JavaScript.FAQTs.com/ Sep 15 '05 #3

 P: n/a "Martin Honnen" wrote: An array object has a sort method to which you can pass your own comparison function if needed that compares what you want to compare e.g. var a = new Array(); a[0] = "entry1 first entry"; a[1] = "entry3 third entry"; a[2] = "entry2 second entry"; var result = a.join('|'); a.sort(function (el1, el2) { var pattern = /^entry(\d+)/g; var n1, n2; pattern.lastIndex = 0; var match1 = pattern.exec(el1); if (match1) { n1 = Number(match1[1]); } pattern.lastIndex = 0; var match2 = pattern.exec(el2); if (match2) { n2 = Number(match2[1]); } if (typeof n1 != 'undefined' && typeof n2 != 'undefined') { return n1 - n2; } else { // no numbers found // could throw an error return -1; } }); result += '\r\n\r\n' + a.join('|'); alert(result); Documentation is here: -- Martin Honnen http://JavaScript.FAQTs.com/ Thanks Martin, that worked quite nicely :-) David Sep 15 '05 #4

 P: n/a David wrote: I have an array of strings. For example... [0] = "entry1 first entry"; [1] = "entry2 second entry"; [2] = "entry3 third entry"; etc... How can I sort this array by the number after "entry"? stringArray= ["entry1 first entry","entry2 second entry","entry3 third entry"] function davidSort(a,b){ return a.split(" ")[0].replace(/[^\d]/g,"")- b.split(" ")[0].replace(/[^\d]/g,""); } alert(stringArray.sort(davidSort).join("\n")) Mick Sep 15 '05 #5

 P: n/a "Mick White" wrote: stringArray= ["entry1 first entry","entry2 second entry","entry3 third entry"] function davidSort(a,b){ return a.split(" ")[0].replace(/[^\d]/g,"")- b.split(" ")[0].replace(/[^\d]/g,""); } alert(stringArray.sort(davidSort).join("\n")) Mick Very elegant and simple. Thanks Mick, it works great. David Sep 15 '05 #6

 P: n/a JRS: In article , dated Thu, 15 Sep 2005 20:37:02, seen in news:comp.lang.javascript, David posted :"Mick White" wrote: stringArray= ["entry1 first entry","entry2 second entry","entry3 third entry"] function davidSort(a,b){ return a.split(" ")[0].replace(/[^\d]/g,"")- b.split(" ")[0].replace(/[^\d]/g,""); } alert(stringArray.sort(davidSort).join("\n")) Mick Very elegant and simple. Thanks Mick, it works great. Like Martin Honnen's method, it will be unnecessarily show for large arrays. The expected number of calls of davidSort is greater than o(N) for an N-element array, and each call performs two non-trivial manoeuvres. For efficiency, do a first pass of o(N) which converts each element to something with the sort key also at the front, do a default (string) sort o(>N), then strip the key taking o(N). The default comparison will, I expect, be quicker than using the fastest possible sort function. The OP did not unambiguously specify the task : he wrote "number" which sometimes means "digit" and sometimes "[sign]digit(s)" etc. You and Martin have, I think, both assumed "number" to mean "string of decimal digits", which is probably what the OP meant. Neither of you, I suspect, handle the general case of a number in any form S acceptable to Number(S). David, please trim your quotes : see newsgroup FAQ. -- © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 © JL/RC: FAQ of news:comp.lang.javascript jscr maths, dates, sources. TP/BP/Delphi/jscr/&c, FAQ items, links. Sep 16 '05 #7

 P: n/a Dr John Stockton wrote: JRS: In article , dated Thu, 15 Sep 2005 20:37:02, seen in news:comp.lang.javascript, David posted :"Mick White" wrote:stringArray=["entry1 first entry","entry2 second entry","entry3 third entry"]function davidSort(a,b){ return a.split(" ")[0].replace(/[^\d]/g,"")- b.split(" ")[0].replace(/[^\d]/g,"");}alert(stringArray.sort(davidSort).join("\n"))MickVery elegant and simple. Thanks Mick, it works great. Like Martin Honnen's method, it will be unnecessarily show for large arrays. The expected number of calls of davidSort is greater than o(N) for an N-element array, and each call performs two non-trivial manoeuvres. For efficiency, do a first pass of o(N) which converts each element to something with the sort key also at the front, do a default (string) sort o(>N), then strip the key taking o(N). The default comparison will, I expect, be quicker than using the fastest possible sort function. The point of my reply was that he needs to extract from the object that portion of which he wants to compare. I'm not quite following what you're saying, I'd love to see a sample. Of course, the ideal solution is to create the array object correctly in the first place. The OP did not unambiguously specify the task : he wrote "number" which sometimes means "digit" and sometimes "[sign]digit(s)" etc. Trivial to do, though "entry-1" is unlikely. You and Martin have, I think, both assumed "number" to mean "string of decimal digits", which is probably what the OP meant. Neither of you, I suspect, handle the general case of a number in any form S acceptable to Number(S). Yes I did Mick Sep 16 '05 #8

 P: n/a JRS: In article , dated Fri, 16 Sep 2005 21:23:02, seen in news:comp.lang.javascript, Mick White posted :Dr John Stockton wrote: Like Martin Honnen's method, it will be unnecessarily show for large arrays. The expected number of calls of davidSort is greater than o(N) for an N-element array, and each call performs two non-trivial manoeuvres. For efficiency, do a first pass of o(N) which converts each element to something with the sort key also at the front, do a default (string) sort o(>N), then strip the key taking o(N). The default comparison will, I expect, be quicker than using the fastest possible sort function.The point of my reply was that he needs to extract from the object thatportion of which he wants to compare. In fact, one does not *need* to *extract* it. I'm not quite following whatyou're saying, I'd love to see a sample. Let T be a string such as "entry1 first entry" matching the first RegExp: T = T.replace(/^(\D*)(\d+)/, "00000\$2\$1\$2") T = T.replace(/^(.*)(\d{6})/, "\$2") The combination of those adds the value of the first "number" part, as a SIX-digit string, to the front of T, now "000001entry1 first entry". There may be better ways. If the elements of the array are all treated as T there is, the array can now be sorted by the default sort, and the original elements can easily be recovered by substringing. For this to be worthwhile, the array must be sufficiently large, and that can only be determined by test since it depends on the browser and script coding. -- © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 © JL/RC: FAQ of news:comp.lang.javascript jscr maths, dates, sources. TP/BP/Delphi/jscr/&c, FAQ items, links. Sep 17 '05 #9

 P: n/a >> The OP did not unambiguously specify the task : he wrote "number" which sometimes means "digit" and sometimes "[sign]digit(s)" etc. You and Martin have, I think, both assumed "number" to mean "string of decimal digits", which is probably what the OP meant. Neither of you, I suspect, handle the general case of a number in any form S acceptable to Number(S). Mick is correct and his solution worked just fine. By number I did mean that I wanted to sort by the decimal digit or numeral. Thank you all for your helpful input. David Sep 20 '05 #10

### This discussion thread is closed

Replies have been disabled for this discussion.