JavaScriptのArray.sortメソッドのデフォルト比較関数

このQ&Aのポイント
  • Array.sortメソッドのデフォルト比較関数について調査しています。
  • 質問者は、プロパティ[name]と[value]を持ったオブジェクトの配列をnameプロパティでソートしたいと考えています。
  • 質問者は、自作の比較関数に代わる標準の比較関数を探しています。
回答を見る
  • ベストアンサー

Array.sortメソッドのデフォルト比較関数

JavaScriptのArray.sortメソッドは、 引数を指定しなければデフォルトの比較関数でソートされますが、 この比較関数を取り出して利用できないでしょうか。 要件は、プロパティ[name]と[value]を持ったオブジェクトの配列のソートです。 nameプロパティは半角英数字の文字列で、これをキーにソートしたいと考えています。 ソートの基準は、Array.sortのデフォルトと同じです。 つまり、こんなコードを想定しています。 var ary = [o1, o2, o3]; // o1~o3はそれぞれ上記のオブジェクト ary.sort(function(a, b){ return compare(a.name, b.name); }); このコードにおけるcompare関数を、Array.sortのデフォルト比較関数にしたいのですが、 これは自前で作成するしかないのでしょうか。 数値だけでなく文字列全般の比較になるので、結構実装が面倒そうなのですが、 自作する場合に何か使えそうな標準関数等、無いでしょうか。 今のところ思いついているのは、下記みたいなものです。 var compare = function(a, b) {  var temp = [a, b];  temp = temp.sort();  return temp[0] === a ? -1 : 1; } 比較関数内で更にArray.sortを呼んで2項目をソートし、 順番が入れ替わったかどうかを判定するだけです。 何だか冗長で気持ち悪いコードですので、代案を探しています。

  • mokpok
  • お礼率62% (154/245)

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

表現がいまいちわかりませんが、無名関数で処理しているところを 普通にユーザー関数に置き換えればよいのでは? <script> var o1={self:"o1",name:"ccc",value:100}; var o2={self:"o2",name:"aaa",value:300}; var o3={self:"o3",name:"ddd",value:400}; var o4={self:"o4",name:"bbb",value:200}; var o5={self:"o5",name:"eee",value:500}; var ary=[o1,o2,o3,o4,o5]; ary.sort(compare_name); for (var i=0;i<ary.length;i++){ document.write(ary[i].self+":"+ary[i].name+":"+ary[i].value+"<br>"); } ary.sort(compare_value); for (var i=0;i<ary.length;i++){ document.write(ary[i].self+":"+ary[i].name+":"+ary[i].value+"<br>"); } function compare_name(a, b){ return (a.name==b.name?0:(a.name>b.name?1:-1)); } function compare_value(a, b){ return (a.value==b.value?0:(a.value>b.value?1:-1)); } </script>

mokpok
質問者

お礼

回答ありがとうございます。 文字列同士の比較演算について、誤解していました。 a.name>b.name これだけで辞書順の比較がされていることを知りませんでした。 なぜか文字数で比較しているだけだと思い込んでいたようです。 普通に比較演算するだけで大丈夫なんですね。 ありがとうございました。

その他の回答 (1)

回答No.2

かいているうちに、さきこされ。 function createCompare (k, d) {  return (d)   ? function (b, a) { return (a[k] > b[k]) - (a[k] < b[k]); }   : function (a, b) { return (a[k] > b[k]) - (a[k] < b[k]); } }; function A (a) { return [a.name, a.value]; } var ary = [  { 'name': 'def', 'value': 456 },  { 'name': 'abc', 'value': 123 },  { 'name': 'ghi', 'value': 789 } ]; var compare = createCompare ('name'); ary.sort (compare); alert (ary.map (A).join ("\n")); var compare = createCompare ('value', true); ary.sort (compare); alert (ary.map (A).join ("\n"));

mokpok
質問者

お礼

回答ありがとうございます。 質問内容ではありませんが、createCompare関数の発想が応用利きそうで参考になります。 クロージャの可能性は無限大ですね。

関連するQ&A

  • STLのsortで、プライベート変数を比較関数に組み入れたい。

    STLのsortで、プライベート変数を比較関数に組み入れたい。 STLのvectorのsortで比較関数を指定してソートをしようとしております。 ソートしようとするvectorは、とあるクラスのプライベート変数であり、 同じクラスの他のプライベート変数を利用した比較を行おうとしています。 例えば int array[4] = {1, 7, 3, 5}; なるプライベート変数があり、比較関数はこんなアルゴリズムとしたいと。 bool compare(int left, int right) { return array[ left ] < array[ right ]; } この compare をクラスのメソッドとして定義して使えるのかなと思っていたのですが コンパイルしたところエラーが出ました。パブリック変数にして、プレディケートの ためのクラスを作って、そこでパブリックメソッドを作って……という方法は見つかった のですが、そのような面倒な方法を経なければいけないのでしょうか。

  • perlで比較関数を使ったソートの仕方

    今、季節をソートするようなプログラムを考えています。 my @array = ('spring','fall','winter','summer'); my @sort = sort number(@array); sub number { if ($a < $b) { return -1; } elsif ($a == $b) { return 0; } elsif ($a > $b) { return 1; } } 実行結果:spring ,summer ,fall ,winter 比較関数を使用して、「春・夏・秋・冬」とソートできるようにしたいです。上のプログラムはまだ途中なんですが、この場合比較関数はどのように実装すればうまくソートできるんでしょうか?分かる方、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ソート Comparator

    Integer型の変数num(10,4,8,6,9,5)をそれぞれ含むオブジェクト配列aryがあり、それをソートするため Arrays.sort(arry,sortLogic); とした場合、 Comparatorインターフェースを実装したクラスsortLogic内のメソッドで public int compare(Object object1, Object object2) {   return ((ary)object1).compareTo(((ary)object2).num); } とすると、昇順にソート(修正ソートマージ)、また、 return ((ary)object1).compareTo(((ary)object2).num); とすると降順にソートされるみたいなのですが、どのような手順(アルゴリズム)でソートされるのでしょうか?

    • ベストアンサー
    • Java
  • javascritp「sort」メソッドについて

    WEB制作初心者、勉強中のものです。 javascritpのsortメソッドについて質問です。 無名関数を使って偶数と奇数を並び替えるコードについてですが、 下記の場合、function(a,b)の引数a,bには、一体どこの数値が入ってるのでしょうか。 var no=[1,2,3,・・・]の中だと思うのですが、、、、a,bが一体何を指すのが 教えていただけないでしょうか? // 『sort』の引数として、使い捨ての関数を作成して利用する var no = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // 配列作成 no.sort(function (a, b) { // 偶数を前に、奇数を後ろにソートする if (a % 2 == 0 && b % 2 != 0) return -1; if (a % 2 != 0 && b % 2 == 0) return 1; return 0; }); alert(no); // 『2, 4, 6, 8, 10, 1, 3, 5, 7, 9』と表示 よろしくお願い致します。

  • Arrayオブジェクトのsort()メソッド

    テキストに書いているArrayオブジェクのsort()メソッドを実行しました。 ソースコードは以下のとおりです。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta http-equiv="Content-type" content="text/html; charset=UTF-8"> <title>Arrayオブジェクトのメソッド</title> <script type="text/javascript"> </script> </head> <body bgcolor="#FFFFFF"> <p style="font-size:200%"> <script type="text/javascript"> var ages = new Array(4, 6, 10, 24, 1, 11, 40); ages = ages.sort(); document.write(ages.join(" > ")); </script> </p> </body> </html> すると、ブラウザにこのように表示されました。 (ちなみに > は矢印記号で大小を比べるものではありません。) 1 > 10 > 11 > 24 > 4 > 40 > 6 これを見る限り数字の順番が変わっています。 テキストでは、これを「文字列として昇順に並び替えた」と書かれているのですが、私の知識の足りなさから意味がよく分かりません。 ただ、昇順の意味は分かっているつもりです。 もし、昇順に並び替えるのなら、 1 > 4 > 6 > 10 > 11 > 24 > 40 のようになるのではないでしょうか。 頭の悪い私のために是非ともアドバイスを頂ければ大変助かるのですが。 どうぞ宜しくお願い致します。

  • 関数で定義した配列のソート

    お世話になります。 配列のソートは xx = new Array(3, 7, 8, 1); xx.sort(); document.write('xx='+xx+'<br>'); function hikaku(a, b) { return(b - a); } yy = new Array(3, 7, 8, 1); yy.sort(hikaku); document.write('yy='+yy+'<br>'); で、できました。 ここで、 function aitem(name,value,date){ this.name=name; this.value=value; this.date=date; } var goods=new Array( new aitem('b',500,'06/05/01'), new aitem('a',200,'06/07/01'), new aitem('d',800,'06/06/01'), new aitem('c',300,'05/09/01'), ); と、配列goodsを定義します。 そして、例えばvalueで並び替えた配列を取得するなんてことはできないでしょうか。 よろしくお願いします。

  • 濁点のソート

    PHPで濁点のソートがうまく出来なくて困っております。 データは下記のような形で入っています。 $temp_array=array("じごい","じこあ","しこう"); sort($temp_array); var_dump($temp_array); 結果は下記のようになってしまいます。 array 0 => string 'しこう' (length=9) 1 => string 'じこあ' (length=9) 2 => string 'じごい' (length=9) 本来であれば濁点を無視した下記のようなソート順にしたいのです。 array 0 => string 'じこあ' (length=9) 1 => string 'じごい' (length=9) 2 => string 'しこう' (length=9) どうしたらいいのでしょうか。 教えてください。

    • 締切済み
    • PHP
  • array_mapの再帰処理がうまく行かない

    長文で失礼します。 array_mapでの再帰処理がうまく行かないのでどこが間違っているか教えてください。 まず、このような配列があります。配列の中に配列があります。 $ary = array(1, 2, null, array("a", null, "c")); この配列の中のnullを"なし"という文字列に変換したいです。 array_mapを使って再帰的にやってみました。 まずはうまく行ったコードから。 ------------------------------------------------------ $ary = array(1, 2, null, array("a", null, "c")); var_dump(null2Nashi($ary)); // nullを"なし"に置換する関数 function null2Nashi(  $in_array ){  if(is_array($in_array)){   return array_map("null2Nashi", $in_array);  } else {   if ($in_array === null){    $in_array = "なし";   }   return $in_array;  } } ------------------------------------------------------ 結果はnullが"なし"に変換されました array (size=4)  0 => int 1  1 => int 2  2 => string 'なし' (length=6)  3 =>   array (size=3)    0 => string 'a' (length=1)    1 => string 'なし' (length=6)    2 => string 'c' (length=1) そしてこの"なし"をコード内で指定するのではなく引数で指定したいと思って無名関数を使って以下のコードにしました。 ------------------------------------------------------ $ary = array(1, 2, null, array("a", null, "c")); var_dump(null2Str($ary, "なし")); // nullを指定文字列に置換する関数 function null2Str(  $in_array, // null値を含む配列  $in_str // null値を変換したい文字列 ){  $n = function($n_array) use($in_str){   if(is_array($n_array)){    return array_map($n, $n_array); //…(1)   } else {    if ($n_array === null){     $n_array = $in_str;    }    return $n_array;   }  };  return $n($in_array); } ------------------------------------------------------ 結果はnullは何も変換されませんでした。 array (size=4)  0 => int 1  1 => int 2  2 => null  3 =>   array (size=3)    0 => string 'a' (length=1)    1 => null    2 => string 'c' (length=1) どうやら(1)のarray_mapが動作していないようです。要素を分解せずに$nの無名関数に渡さずにそのまま第2引数を返しているだけみたいです。 何か対応方法があるでしょうか? どうぞよろしくお願い致します。

    • ベストアンサー
    • PHP
  • 文字と数字が混在する要素のsortについて

    お世話になっております。 javascript初心者です。 以下のような要素を時系列でsortするにはどうすればいいでしょうか? <ul> <li>テキストを時系列で並び替えたい 2011/05/15/19:00</li> <li>テキストを時系列で並び替えたい 2009/01/15/14:00</li> <li>テキストを時系列で並び替えたい 2010/05/15/19:00</li> </ul> liの中のテキストをArrayオブジェクトに代入して配列にした後 sortでどのような処理をすればいいのでしょうか? 例えば var myArray = new Array(); でmyArrayと言う配列オブジェクトにliのテキストを代入したときに myArray.sort(function(a,b) {return a-b;}); とすれば比較要素が単体数字の場合はソートできるのですが 文字と/など複合数字が混在しているとソートできません。

  • 連想二次元配列のUNIXTIMEでのソート

    ID(主キー)、unixtime、nameをフィールド名とするとするSQLのデータベースを取得してUNIXTIMEを比較してソートするようなPHPを作りました。   $contents= array(); $temp = mysql_query($query, $link ); while( $contents = mysql_fetch_array($temp, MYSQL_ASSOC)){ } //比較してソート function cmp($a, $b) { print_r($a); if ($a["unixtime"] == $b["unixtime"]) { return 0; } return ((int)$a["unixtime"] < (int)$b["unixtime"]) ? 1 : -1; } usort($contents, "cmp"); しかしこれを実行したところ、 Warning: usort() expects parameter 1 to be array, boolean given in C:\xampp\htdocs\php\outstr.php on line 49 となってしまいます。 usortのエラーのようですが、なぜこうなってしまうのでしょうか。 正常にソートできるような方法を教えてください。

    • ベストアンサー
    • PHP

専門家に質問してみよう