Javascriptのsortがstableであることの確認

やあ子供たち。
「最近のブラウザ上で走るjavascriptのsort()関数は、すっかりStableな sort になっている」ということのようなので、実験してみたよ。ま、それだけの内容のつまらないポストだけれども、中盤あたりの、比較関数定義(comp_*という名前)のところで、「arrow演算子におけるreturnの省略」というものに挑戦してみたよ!コメントアウトしたコードブロックはすべてその直下の、{}やreturnを省略した形にかけるので、是非みんなもこれは覚えてしまってほしい。
今日実はそのようなコードを見つけてしまってね、もしやと思って「javascript omit return」などで検索してみるといろいろ出てきたよ!やっぱりそうだったんだ!ってことでこれは便利なのでどんどん使いたい。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Cache-Control"content="no-cache">
  <title>This is Tab TItle</title>
<style>
  /* スタイルシートコードを記述 */
  #placeholder1
  {
    display: flex;
  }
  .phc
  {
    background-color: lightgreen;
    margin: 5px;
  }
</style>
</head>
<body>
  <!-- HTML部品設置を記述 -->
  <h4 id="hello">Hello Stable Sort (ECMA Script 2019).</h4>
  <div id="placeholder1"></div>
  <script type="text/javascript">
    // ***javascriptのプログラムを記述***
    window.addEventListener("DOMContentLoaded",function(){
    });
    let arr=[
      {name: "grape", price: 350},
      {name: "acai berry", price: 700},
      {name: "apple", price: 150},
      {name: "apricot", price: 400},
      {name: "melon", price: 1280},
      {name: "banana", price: 150},
      {name: "blueberry", price: 350},
      {name: "melon", price: 800},
      {name: "banana", price: 90},
      {name: "guava", price: 700},
      {name: "banana", price: 590},
      {name: "orange", price: 150},
      {name: "muscat", price:1280},
      {name: "mango", price: 700},
    ];
    function dump_arrow()
    {
      let phc = document.createElement("div");
      {
        phc.textContent = "→";
      }
      document.getElementById("placeholder1").appendChild(phc);
    }
    function dump( title, arr, name_colorId, price_colorId )
    {
      let phc = document.createElement("div");
      phc.className = "phc";
      {
        phc.textContent = title;
        phc.appendChild( document.createElement("hr"));
      }
      {
        let table = document.createElement("table");
        for( let item of arr )// for..ofループ(Isn't it Handy!)
        {
          let tr = document.createElement("tr");
          {
            let td1 = document.createElement("td");td1.textContent=item.name;
            td1.style = "background-color: "+name_colorId.get(item.name);
            let td2 = document.createElement("td");td2.textContent=item.price;
            td2.style.backgroundColor = price_colorId.get(item.price);
            tr.appendChild(td1);
            tr.appendChild(td2);
          }
          table.appendChild(tr);
        }// item
        phc.appendChild(table);
      }
      document.getElementById("placeholder1").appendChild(phc);
      return;
    }
    function uniq(array) {
      return Array.from(new Set(array));
    }
    // let for_name=(a)=>{return a.name;}
    // let for_price=(a)=>{return a.price;}
    // let comp = (a,b,f)=>{return f(a)<f(b)?-1:1;}
    // let comp_by_name = (a,b)=>{return comp(a,b,for_name);}
    // let comp_by_price = (a,b)=>{return comp(a,b,for_price);}
    // let comp_by_name_i = (a,b)=>{return -1*comp(a,b,for_name);}
    // let comp_by_price_i = (a,b)=>{return -1*comp(a,b,for_price);}    
    let for_name= a=>a.name;
    let for_price= a=>a.price;
    let comp = (a,b,f)=>f(a)<f(b)?-1:1;
    let comp_by_name = (a,b)=>comp(a,b,for_name);
    let comp_by_price = (a,b)=>comp(a,b,for_price);
    let comp_by_name_i = (a,b)=>-1*comp(a,b,for_name);
    let comp_by_price_i = (a,b)=>-1*comp(a,b,for_price);
    let name_colorId;
    let price_colorId;
    {
      function calc_colorId(arr,f)
      {
        let tmparr=[];
        for( let ipr of arr )
          tmparr.push( f(ipr) );
        tmparr = uniq(tmparr);
        let cnt=0;
        let result =[];
        for(let ival of tmparr)
        {
          result.push(
            {
              key: ival, 
              color_id: cnt, 
              rgb: grads(cnt/(tmparr.length-1)),
            });
          console.log( ival+":"+cnt+","+tmparr.length+"--"+cnt/(tmparr.length-1)+"--"+grads(cnt/(tmparr.length-1)));
          ++cnt;
        }
        const map1 = new Map(
          result.map(object => {
            return [object.key, object.rgb];
          }),
        );        
        return map1;
      } 
      let arr2 = [...arr];
      arr2.sort(comp_by_name);
      name_colorId = calc_colorId( arr2, for_name);
      arr2.sort(comp_by_price);
      price_colorId = calc_colorId( arr2, for_price);
      console.log( name_colorId );
      console.log( price_colorId );
    }
    dump( "初期状態リスト", arr, name_colorId, price_colorId  );
    dump_arrow();
    arr.sort(comp_by_name);    
    dump( "フルーツ名で順ソート", arr, name_colorId, price_colorId  );
    dump_arrow();
    arr.sort(comp_by_price);
    dump( "フルーツの価格で順ソート", arr, name_colorId, price_colorId  );
    dump_arrow();
    arr.sort(comp_by_name);
    dump( "フルーツ名で順ソート", arr, name_colorId, price_colorId  );
    dump_arrow();
    arr.sort(comp_by_price);
    dump( "フルーツの価格で順ソート", arr, name_colorId, price_colorId  );

    // 参考URL
    // ① https://lab.syncer.jp/Web/JavaScript/Snippet/60/
    // ② https://lab.syncer.jp/Web/JavaScript/Snippet/67/
    function rgb2hex ( rgb ) {
      return "#" + rgb.map( function ( value ) {
        return ( "0" + value.toString( 16 ) ).slice( -2 ) ;
      } ).join( "" ) ;
    }
    function grads( val ) {
      let ival = parseInt(val*255);
      return rgb2hex( [ival, 255-ival, ival] );
    }
  </script>
</body>
</html>