JavaScriptのArrayオブジェクトには組み込みで、sortメソッドが用意されている。でも、sortメソッドは文字列としてソートしてしまうので、要素が全て数字で数字順に並び替えるときには使えない。
例えば、
var test = new Array(10,0,5); test.sort(); alert(test);
の結果は「0,10,5」となってしまう。
対応策は、人力検索の質問に回答があって、並び順を指定する関数を渡せば良いとのこと。
var test = new Array(10,0,5); test.sort(function(a, b) { return (parseInt(a) > parseInt(b)) ? 1 : -1; }); alert(test);
これで結果が「0,5,10」となる。
Arrayオブジェクトのプロトタイプに追加してしまうとこんな感じか。
Array.prototype.sortByNumber = function() { this.sort(function(a, b) { return (parseInt(a) > parseInt(b)) ? 1 : -1; }); }
これで全然問題ないのだけど、最近まともにプログラム書いてないので、リハビリがてらに数値ソートを自作してみた。
Array.prototype.sortByNumber = function() { var ori = this; var res = new Array(); for (var i = 0; i < ori.length; i++) { var x = ori[i]; if (typeof x != "number") { return false; } // Array.length == 0. if (res.length == 0) { res[0] = x; // Array.length == 1. } else if (res.length == 1) { if (x > res[0]) { res[1] = x; } else { var tmp = res[0]; res[0] = x; res[1] = tmp; } // Array.length > 2. } else { var buf = new Array(); // Min if (x <= res[0]) { buf[0] = x; for (var rk = 0; rk < res.length; rk++) { buf[buf.length] = res[rk]; } res = buf; // Max } else if (x >= res[res.length - 1]) { res[res.length] = x; // Between } else { var index; for (var rk = 0; rk < res.length; rk++) { var here = res[rk]; var next = res[rk + 1]; if (x >= here && x <= next) { index = rk + 1; } } for (var rk = 0; rk < index; rk++) { buf[buf.length] = res[rk]; } buf[buf.length] = x; for (var rk = index; rk < res.length; rk++) { buf[buf.length] = res[rk]; } res = buf; } } } return res; } // Test code. var test = new Array( 20,1,-1,4,10,3,12,11,2,100,11.124,22,43,-50,3.5 ); alert(test.sortByNumber());
ちなみに、ベンチを取ると明らかに組み込みのsortを使ったほうが速いので、リハビリコードは使わないようにしましょう。