配列のソートを利用して簡単に探索結果の並び変えをやってみる

[ヴァル研究所 Advent Calendar 2016](http://qiita.com/advent-calendar/2016/val) の９日目はJavaScriptに関するお話です。

# JavaScriptは簡単だけど、複雑・・・

JavaScriptって簡単に実装できる代わり、バージョンがいっぱいあったりブラウザ依存で動いたり動かなかったり、いろいろなライブラリなんかもあって良く分からなくなることありませんか？
今でも「このブラウザでは動く」、「特定のブラウザで動かない」なんてことを耳にします。

何となくやっちゃうプログラミングと駅すぱあとにも応用できるソートについて紹介します。

# 配列をソートしてみる

たとえば、こんな感じの配列があったとします。

```Javascript
var list = [5, 1, 6, 2, 9, 3, 7, 4, 8];
```

これをソートする場合、こんな感じで実装していませんか？

```Javascript
for (var i = 0; i < list.length; i++) {
    for (var j = i + 1; j < list.length; j++) {
        if (list[i] > list[j]) {
            var temporary = list[i];
            list[i] = list[j];
            list[j] = temporary;
        }
    }
}
```

動かないわけじゃないし、説明も簡単なので、プログラミングのお勉強で書いたことあるって人も多いのではないでしょうか？

# Array.prototype.sort()を使ってみる

Arrayのsortを使うとすごく簡単にソートが実装できます。

```Javascript
list.sort(function (a, b) {
    if (a > b) return 1;
    if (a < b) return -1;
    return 0;
});
```

これで「1,2,3,4,5,6,7,8,9」が取得できます。
しかも、結構古めのブラウザでも対応していて、今なら依存などはほぼ考えなくて大丈夫ですね。
(というより、現時点でサポートされているブラウザのほとんどが対応してます)

（sortの詳細は https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort を参照）

# 本題！探索結果をソートしてみる

経路探索については4日目を見てね。
[ヴァル研究所 Advent Calendar 2016、4日目](http://qiita.com/valsitoh/items/79a8902a2e7ad547015d)

さて、探索結果のソートです。
用意した探索結果を早速料理していきましょう。

```
{"ResultSet":{"apiVersion":"1.27.0.0","engineVersion":"201612_02a","Course":[{"searchType":"plain","dataType":"plain","SerializeData":"VkV4QaEByALDAqYBM6KyA6YBM6KyBJHCAUMAAAACpgEzorIDyAEBAgEDAQQBBwEIAQoCD0JAAAWSwQKlWI_BAqVY1QaRwwEEAgEDwQGk3QeRxQGmATOitgOBBIEFAAgACJHEBAEFAQekbQgBCZHBAwEPkcUBkgABApHDAQACAAMAA5HDAQACAAMABJEABZEA--T3221233232319:F3321122120:A23121141:--a7acdaacc1ab2bd0f3f92adf3e4abaa62e257cc3--0--0--0--144","Price":[{"kind":"FareSummary","Oneway":"160","Round":"320"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Fare","index":"1","selected":"true","Type":"Fare","Oneway":"160","Round":"320"},{"kind":"Teiki1Summary","Oneway":"4850"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki1","index":"1","selected":"true","Type":"Teiki1","Oneway":"4850"},{"kind":"Teiki3Summary","Oneway":"13820"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki3","index":"1","selected":"true","Type":"Teiki3","Oneway":"13820"},{"kind":"Teiki6Summary","Oneway":"23260"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki6","index":"1","selected":"true","Type":"Teiki6","Oneway":"23260"}],"Route":{"timeOther":"6","timeOnBoard":"6","exhaustCO2":"127","exhaustCO2atPassengerCar":"974","distance":"58","timeWalk":"0","transferCount":"0","Line":{"direction":"Up","stopStationCount":"1","teiki3Index":"1","teiki6Index":"1","timeOnBoard":"6","exhaustCO2":"127","fareIndex":"1","exhaustCO2atPassengerCar":"974","distance":"58","teiki1Index":"1","Name":"ＪＲ中央線快速","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ中央線快速","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"250060002"},"Point":[{"Station":{"code":"22671","Name":"高円寺","Type":"train","Yomi":"こうえんじ"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.39.10.89","lati":"35.42.7.59","longi_d":"139.653027","gcs":"tokyo","lati_d":"35.70211"}},{"Station":{"code":"22741","Name":"新宿","Type":"train","Yomi":"しんじゅく"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.11.0","lati":"35.41.15.0","longi_d":"139.703056","gcs":"tokyo","lati_d":"35.6875"}}]}},{"searchType":"plain","dataType":"plain","SerializeData":"VkV4QaEByQLDAqYBM6KyA6YBM6KyBJHCAUMAAAACpgEzorIDyAEBAgEDAQQBBwEIAQoCD0JAAAWUwQKlWI_BAqVZQcECpVkGwQKlWNUGk8MBBAIBA8EBpQGFwwEEAgEDwQGlBIjDAQQCAQPBAaS4B5PFAaYBM6K2A4EEgQUgCADGAaYBM6K2AgEDgQSBBRAIAMYBpgEzorYCAgOBBIEFAAgACJPEBAEFAQekbggBxgIBBAIFAQYBB6UBSwgCxQICBAMFAQelAs0IAwmSwgIBAwHDAQICAgMBCpOgwwEBAgEDAcIBAgICD5HFAZQAAQIDApPDAQACAAMAwwEBAgEDAcMBAgICAwIDk8MBAAIAAwDDAQECAQMBwwECAgIDAgSSAAEFkQE*--T3221233232319:F3321122120:A23121141:--e5b02b81e77e4c7c56baeb0a262e3e3950553d8d--0--0--0--293","Price":[{"kind":"FareSummary","Oneway":"430","Round":"860"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"1","kind":"Fare","index":"1","selected":"true","Type":"Fare","Oneway":"290","Round":"580"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"3","kind":"Fare","index":"2","selected":"true","Type":"Fare","Oneway":"140","Round":"280"},{"kind":"Teiki1Summary","Oneway":"14400"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki1","index":"1","selected":"true","Type":"Teiki1","Oneway":"3880"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki1","index":"2","selected":"true","Type":"Teiki1","Oneway":"6640"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"3","kind":"Teiki1","index":"3","selected":"true","Type":"Teiki1","Oneway":"3880"},{"kind":"Teiki3Summary","Oneway":"41050"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki3","index":"1","selected":"true","Type":"Teiki3","Oneway":"11060"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki3","index":"2","selected":"true","Type":"Teiki3","Oneway":"18930"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"3","kind":"Teiki3","index":"3","selected":"true","Type":"Teiki3","Oneway":"11060"},{"kind":"Teiki6Summary","Oneway":"73100"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki6","index":"1","selected":"true","Type":"Teiki6","Oneway":"18620"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki6","index":"2","selected":"true","Type":"Teiki6","Oneway":"35860"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"3","kind":"Teiki6","index":"3","selected":"true","Type":"Teiki6","Oneway":"18620"}],"Route":{"timeOther":"9","timeOnBoard":"12","exhaustCO2":"176","exhaustCO2atPassengerCar":"1344","distance":"80","timeWalk":"0","transferCount":"1","Line":[{"direction":"Up","stopStationCount":"0","teiki3Index":"1","teiki6Index":"1","timeOnBoard":"2","exhaustCO2":"30","fareIndex":"1","exhaustCO2atPassengerCar":"235","distance":"14","teiki1Index":"1","Name":"ＪＲ総武線","Type":"train","ArrivalState":{"Type":"extension","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ総武線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255222000"},{"direction":"Down","stopStationCount":"1","teiki3Index":"2","teiki6Index":"2","timeOnBoard":"6","exhaustCO2":"85","fareIndex":"1","exhaustCO2atPassengerCar":"655","distance":"39","teiki1Index":"2","Name":"東京メトロ東西線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"東京メトロ東西線","TimeReliability":"none","DepartureState":{"Type":"extension","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"012118255"},{"direction":"Down","stopStationCount":"1","teiki3Index":"3","teiki6Index":"3","timeOnBoard":"4","exhaustCO2":"59","fareIndex":"2","exhaustCO2atPassengerCar":"453","distance":"27","teiki1Index":"3","Name":"ＪＲ山手線内回り","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ山手線内回り","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"045232013"}],"Point":[{"Station":{"code":"22671","Name":"高円寺","Type":"train","Yomi":"こうえんじ"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.39.10.89","lati":"35.42.7.59","longi_d":"139.653027","gcs":"tokyo","lati_d":"35.70211"}},{"Station":{"code":"22849","Name":"中野(東京都)","Type":"train","Yomi":"なかの"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.40.9.0","lati":"35.42.9.29","longi_d":"139.669167","gcs":"tokyo","lati_d":"35.702582"}},{"Station":{"code":"22790","Name":"高田馬場","Type":"train","Yomi":"たかだのばば"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.27.0","lati":"35.42.36.39","longi_d":"139.7075","gcs":"tokyo","lati_d":"35.710111"}},{"Station":{"code":"22741","Name":"新宿","Type":"train","Yomi":"しんじゅく"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.11.0","lati":"35.41.15.0","longi_d":"139.703056","gcs":"tokyo","lati_d":"35.6875"}}]}},{"searchType":"plain","dataType":"plain","SerializeData":"VkV4QaEByQLDAqYBM6KyA6YBM6KyBJHCAUMAAAACpgEzorIDyAEBAgEDAQQBBwEIAQoCD0JAAAWTwQKlWI_BAqVZmMECpVjVBpLDAQQCAQPBAaUBhcMBBAIBA8EBpQflB5LFAaYBM6K2A4EEgQUACADGAaYBM6K2AgEDgQSBBQAIAAiSxAQBBQEHpG4IAcUCAQQCBQEHpQLRCAIJksEDAcMBAQIBAwEKkqDDAQECAQMBD5HFAZMAAQICksMBAAIAAwDDAQECAQMBA5LDAQACAAMAwwEBAgEDAQSSAAEFkQE*--T3221233232319:F3321122120:A23121141:--07535bbdf639e8238e41c45659537e0269a46c6a--0--0--0--224","Price":[{"kind":"FareSummary","Oneway":"340","Round":"680"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Fare","index":"1","selected":"true","Type":"Fare","Oneway":"160","Round":"320"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Fare","index":"2","selected":"true","Type":"Fare","Oneway":"180","Round":"360"},{"kind":"Teiki1Summary","Oneway":"12290"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki1","index":"1","selected":"true","Type":"Teiki1","Oneway":"4850"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki1","index":"2","selected":"true","Type":"Teiki1","Oneway":"7440"},{"kind":"Teiki3Summary","Oneway":"35030"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki3","index":"1","selected":"true","Type":"Teiki3","Oneway":"13820"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki3","index":"2","selected":"true","Type":"Teiki3","Oneway":"21210"},{"kind":"Teiki6Summary","Oneway":"63440"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki6","index":"1","selected":"true","Type":"Teiki6","Oneway":"23260"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki6","index":"2","selected":"true","Type":"Teiki6","Oneway":"40180"}],"Route":{"timeOther":"14","timeOnBoard":"12","exhaustCO2":"156","exhaustCO2atPassengerCar":"1192","distance":"71","timeWalk":"0","transferCount":"1","Line":[{"direction":"Up","stopStationCount":"1","teiki3Index":"1","teiki6Index":"1","timeOnBoard":"4","exhaustCO2":"72","fareIndex":"1","exhaustCO2atPassengerCar":"554","distance":"33","teiki1Index":"1","Name":"ＪＲ総武線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ総武線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255222000"},{"direction":"Up","stopStationCount":"3","teiki3Index":"2","teiki6Index":"2","timeOnBoard":"8","exhaustCO2":"83","fareIndex":"2","exhaustCO2atPassengerCar":"638","distance":"38","teiki1Index":"2","Name":"都営大江戸線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"都営大江戸線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255107107"}],"Point":[{"Station":{"code":"22671","Name":"高円寺","Type":"train","Yomi":"こうえんじ"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.39.10.89","lati":"35.42.7.59","longi_d":"139.653027","gcs":"tokyo","lati_d":"35.70211"}},{"Station":{"code":"22936","Name":"東中野","Type":"train","Yomi":"ひがしなかの"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.41.12.50","lati":"35.42.11.0","longi_d":"139.686806","gcs":"tokyo","lati_d":"35.703056"}},{"Station":{"code":"22741","Name":"新宿","Type":"train","Yomi":"しんじゅく"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.11.0","lati":"35.41.15.0","longi_d":"139.703056","gcs":"tokyo","lati_d":"35.6875"}}]}},{"searchType":"plain","dataType":"plain","SerializeData":"VkV4QaEByQLDAqYBM6KyA6YBM6KyBJHCAUMAAAACpgEzorIDyAEBAgEDAQQBBwEIAQoCD0JAAAWVwQKlWI_BAqVZmMECpVk8wQKlWQbBAqVY1QaUwwEEAgEDwQGlAYXDAQQCAQPBAaUH5MMBBAIBA8EBpQNrwwEEAgEDwQGkuAeUxQGmATOitgOBBIEFAAgAxgGmATOitgIBA4EEgQUACADGAaYBM6K2AgIDgQSBBQAIAMYBpgEzorYCAwOBBIEFAAgACJTEBAEFAQekbggBxgIBBAIFAQYBB6UC0QgCxQICBAMFAQelASAIA8UCAwQEBQEHpQLNCAQJk8EDAcMBAQICAwHDAQMCAwMBCpOgwwEBAgEDAcMBAgIDAwEPkcUBlQABAgMEApTDAQACAAMAwwEBAgEDAcMBAgICAwLDAQMCAwMDA5TDAQACAAMAwwEBAgEDAcMBAgICAwLDAQMCAwMDBJMAAQIFkgEC--T3221233232319:F3321122120:A23121141:--3bba9b2beec52b0f1f63740af2e55329bf38eb54--0--0--0--363","Price":[{"kind":"FareSummary","Oneway":"610","Round":"1220"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Fare","index":"1","selected":"true","Type":"Fare","Oneway":"160","Round":"320"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"2","kind":"Fare","index":"2","selected":"true","Type":"Fare","Oneway":"310","Round":"620"},{"fareRevisionStatus":"none","toLineIndex":"4","fromLineIndex":"4","kind":"Fare","index":"3","selected":"true","Type":"Fare","Oneway":"140","Round":"280"},{"kind":"Teiki1Summary","Oneway":"20500"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki1","index":"1","selected":"true","Type":"Teiki1","Oneway":"4850"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki1","index":"2","selected":"true","Type":"Teiki1","Oneway":"6340"},{"fareRevisionStatus":"none","toLineIndex":"4","fromLineIndex":"3","kind":"Teiki1","index":"3","selected":"true","Type":"Teiki1","Oneway":"9310"},{"kind":"Teiki3Summary","Oneway":"58430"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki3","index":"1","selected":"true","Type":"Teiki3","Oneway":"13820"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki3","index":"2","selected":"true","Type":"Teiki3","Oneway":"18070"},{"fareRevisionStatus":"none","toLineIndex":"4","fromLineIndex":"3","kind":"Teiki3","index":"3","selected":"true","Type":"Teiki3","Oneway":"26540"},{"kind":"Teiki6Summary","Oneway":"105450"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki6","index":"1","selected":"true","Type":"Teiki6","Oneway":"23260"},{"fareRevisionStatus":"none","toLineIndex":"2","fromLineIndex":"2","kind":"Teiki6","index":"2","selected":"true","Type":"Teiki6","Oneway":"34240"},{"fareRevisionStatus":"none","toLineIndex":"4","fromLineIndex":"3","kind":"Teiki6","index":"3","selected":"true","Type":"Teiki6","Oneway":"47950"}],"Route":{"timeOther":"19","timeOnBoard":"13","exhaustCO2":"191","exhaustCO2atPassengerCar":"1461","distance":"87","timeWalk":"0","transferCount":"3","Line":[{"direction":"Up","stopStationCount":"1","teiki3Index":"1","teiki6Index":"1","timeOnBoard":"4","exhaustCO2":"72","fareIndex":"1","exhaustCO2atPassengerCar":"554","distance":"33","teiki1Index":"1","Name":"ＪＲ総武線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ総武線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255222000"},{"direction":"Down","stopStationCount":"0","teiki3Index":"2","teiki6Index":"2","timeOnBoard":"2","exhaustCO2":"17","fareIndex":"2","exhaustCO2atPassengerCar":"134","distance":"8","teiki1Index":"2","Name":"都営大江戸線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"都営大江戸線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255107107"},{"direction":"Up","stopStationCount":"1","teiki3Index":"3","teiki6Index":"3","timeOnBoard":"3","exhaustCO2":"41","fareIndex":"2","exhaustCO2atPassengerCar":"319","distance":"19","teiki1Index":"3","Name":"西武新宿線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"西武新宿線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255238000"},{"direction":"Down","stopStationCount":"1","teiki3Index":"3","teiki6Index":"3","timeOnBoard":"4","exhaustCO2":"59","fareIndex":"3","exhaustCO2atPassengerCar":"453","distance":"27","teiki1Index":"3","Name":"ＪＲ山手線内回り","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ山手線内回り","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"045232013"}],"Point":[{"Station":{"code":"22671","Name":"高円寺","Type":"train","Yomi":"こうえんじ"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.39.10.89","lati":"35.42.7.59","longi_d":"139.653027","gcs":"tokyo","lati_d":"35.70211"}},{"Station":{"code":"22936","Name":"東中野","Type":"train","Yomi":"ひがしなかの"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.41.12.50","lati":"35.42.11.0","longi_d":"139.686806","gcs":"tokyo","lati_d":"35.703056"}},{"Station":{"code":"22844","Name":"中井","Type":"train","Yomi":"なかい"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.41.23.0","lati":"35.42.41.0","longi_d":"139.689722","gcs":"tokyo","lati_d":"35.711389"}},{"Station":{"code":"22790","Name":"高田馬場","Type":"train","Yomi":"たかだのばば"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.27.0","lati":"35.42.36.39","longi_d":"139.7075","gcs":"tokyo","lati_d":"35.710111"}},{"Station":{"code":"22741","Name":"新宿","Type":"train","Yomi":"しんじゅく"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.11.0","lati":"35.41.15.0","longi_d":"139.703056","gcs":"tokyo","lati_d":"35.6875"}}]}},{"searchType":"plain","dataType":"plain","SerializeData":"VkV4QaEByALDAqYBM6KyA6YBM6KyBJHCAUMAAAACpgEzorIDyAEBAgEDAQQBBwEIAQoCD0JEAAWVwQKlWI_BAqVZmMECpVlCwQKlcp7BAqVY1QaUwwEEAgEDwQGlAYXDAQQCAQPBAaUH5cMBBAIBA8EBpQSDwwEEAgUDwQEBB5TFAaYBM6K2A4EEgQUACADGAaYBM6K2AgEDgQSBBQAIAMYBpgEzorYCAgOBBIEFAAgAxgGmATOitgIDA4EEgQUACAAIlMQEAQUBB6RuCAHFAgEEAgUBB6UC0QgCxQICBAMFAQelAUgIA8UCAwQEBQIHAQlEk2uV4AmSwQMBwwEBAgIDAQ|RxQGVAAECAwQClMMBAAIAAwDDAQECAQMBwwECAgIDAsMBAwIDAwMDlMMBAAIAAwDDAQECAQMBwwECAgIDAsMBAwIDAwMEkgABBZIAAA**--T3221233232319:F3321122120:A23121141:--729dc5f661611fadd1bc319e082d09d7037025cc--0--0--0--337","Price":[{"kind":"FareSummary","Oneway":"440","Round":"880"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Fare","index":"1","selected":"true","Type":"Fare","Oneway":"160","Round":"320"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"2","kind":"Fare","index":"2","selected":"true","Type":"Fare","Oneway":"280","Round":"560"},{"kind":"Teiki1Summary","Oneway":"15600"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki1","index":"1","selected":"true","Type":"Teiki1","Oneway":"4850"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"2","kind":"Teiki1","index":"2","selected":"true","Type":"Teiki1","Oneway":"10750"},{"kind":"Teiki3Summary","Oneway":"44470"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki3","index":"1","selected":"true","Type":"Teiki3","Oneway":"13820"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"2","kind":"Teiki3","index":"2","selected":"true","Type":"Teiki3","Oneway":"30650"},{"kind":"Teiki6Summary","Oneway":"81320"},{"fareRevisionStatus":"none","toLineIndex":"1","fromLineIndex":"1","kind":"Teiki6","index":"1","selected":"true","Type":"Teiki6","Oneway":"23260"},{"fareRevisionStatus":"none","toLineIndex":"3","fromLineIndex":"2","kind":"Teiki6","index":"2","selected":"true","Type":"Teiki6","Oneway":"58060"}],"Route":{"timeOther":"19","timeOnBoard":"10","exhaustCO2":"136","exhaustCO2atPassengerCar":"1041","distance":"62","timeWalk":"2","transferCount":"2","Line":[{"direction":"Up","stopStationCount":"1","teiki3Index":"1","teiki6Index":"1","timeOnBoard":"4","exhaustCO2":"72","fareIndex":"1","exhaustCO2atPassengerCar":"554","distance":"33","teiki1Index":"1","Name":"ＪＲ総武線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"ＪＲ総武線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255222000"},{"direction":"Up","stopStationCount":"0","teiki3Index":"2","teiki6Index":"2","timeOnBoard":"2","exhaustCO2":"22","fareIndex":"2","exhaustCO2atPassengerCar":"168","distance":"10","teiki1Index":"2","Name":"都営大江戸線","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"都営大江戸線","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255107107"},{"direction":"Up","stopStationCount":"1","teiki3Index":"2","teiki6Index":"2","timeOnBoard":"4","exhaustCO2":"41","fareIndex":"2","exhaustCO2atPassengerCar":"319","distance":"19","teiki1Index":"2","Name":"東京メトロ丸ノ内線(池袋－荻窪)","Type":"train","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"東京メトロ丸ノ内線(池袋－荻窪)","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"255002014"},{"direction":"Up","stopStationCount":"0","timeOnBoard":"2","exhaustCO2":"0","exhaustCO2atPassengerCar":"0","distance":"0","Name":"徒歩","Type":"walk","ArrivalState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"TypicalName":"徒歩","TimeReliability":"none","DepartureState":{"Type":"normal","Datetime":{"text":"2016-12-06","operation":"today"}},"Color":"230230230"}],"Point":[{"Station":{"code":"22671","Name":"高円寺","Type":"train","Yomi":"こうえんじ"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.39.10.89","lati":"35.42.7.59","longi_d":"139.653027","gcs":"tokyo","lati_d":"35.70211"}},{"Station":{"code":"22936","Name":"東中野","Type":"train","Yomi":"ひがしなかの"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.41.12.50","lati":"35.42.11.0","longi_d":"139.686806","gcs":"tokyo","lati_d":"35.703056"}},{"Station":{"code":"22850","Name":"中野坂上","Type":"train","Yomi":"なかのさかうえ"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.41.9.0","lati":"35.41.38.0","longi_d":"139.685833","gcs":"tokyo","lati_d":"35.693889"}},{"Station":{"code":"29342","Name":"新宿(東京メトロ)","Type":"train","Yomi":"しんじゅく"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.15.0","lati":"35.41.21.0","longi_d":"139.704167","gcs":"tokyo","lati_d":"35.689167"}},{"Station":{"code":"22741","Name":"新宿","Type":"train","Yomi":"しんじゅく"},"Prefecture":{"code":"13","Name":"東京都"},"GeoPoint":{"longi":"139.42.11.0","lati":"35.41.15.0","longi_d":"139.703056","gcs":"tokyo","lati_d":"35.6875"}}]}}]}}
```

まず、経路は下記のようになっています。

1. 高円寺→新宿
1. 高円寺→中野(東京都)→高田馬場→新宿
1. 高円寺→東中野→新宿
1. 高円寺→東中野→中井→高田馬場→新宿
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿

そして、もちろん先ほどのsortを使っていきます。
しかし、変数はオブジェクトになってしまっているため、これをそのままソートすることはできません。
たとえば、こんな感じで実行しようとしても「list.sort is not a function」と出てしまいます。

```Javascript
var list = JSON.parse(探索結果のＪＳＯＮ文字列);
list.sort(function (a, b) {
    if (a > b) return 1;
    if (a < b) return -1;
    return 0;
});
```

困りましたね。

でも実は単にどれを見てソートするか、分かっていないことが原因です。
探索結果には金額や距離、時間など様々な要素がありますので、どの項目でソートするか、ちゃんと指定しなければなりません。
さらに、JSONをパースした際、list変数にResultSetが入りますが、ここがArrayでないことも原因です。

## まずは、ソート対象となるArrayを特定する

結論としては ResultSet / Course がソート対象となる配列です。
また、配列かどうかわからない場合、instanceof を使うと便利です。
早速実装していきましょう。

## 乗り換え回数の少ない順にソートしてみる

ソート前の乗り換え回数の順番を確認してみましょう。

```Javascript
if (list.ResultSet.Course instanceof Array) {
    var buffer = new Array();
    for (var i = 0; i < list.ResultSet.Course.length; i++) {
        buffer.push(list.ResultSet.Course[i].Route.transferCount);
    }
    alert(buffer.join(","));
}
```

経路のインデックスと乗り換え回数の対応は下記の通りです。

1. 高円寺→新宿 **0回**
1. 高円寺→中野(東京都)→高田馬場→新宿 **1回**
1. 高円寺→東中野→新宿 **1回**
1. 高円寺→東中野→中井→高田馬場→新宿 **3回**
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿 **2回**

※第二経路の中野は乗り入れのため乗り換え回数にカウントしません。
※第五経路の新宿(東京メトロ)～新宿間は徒歩移動のため、乗り換え回数にカウントしません。

そして、ソートの本体はこちらです。

```Javascript
if (list.ResultSet.Course instanceof Array) {
    // ソートを追加
    list.ResultSet.Course.sort(function (a, b) {
        if (a.Route.transferCount > b.Route.transferCount) return 1;
        if (a.Route.transferCount < b.Route.transferCount) return -1;
        return 0;
    });
    var buffer = new Array();
    for (var i = 0; i < list.ResultSet.Course.length; i++) {
        buffer.push(list.ResultSet.Course[i].Route.transferCount);
    }
    alert(buffer.join(","));
}
```

ソートを実行した結果が下記です。

1. 高円寺→新宿 **0回**
1. 高円寺→中野(東京都)→高田馬場→新宿 **1回**
1. 高円寺→東中野→新宿 **1回**
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿 **2回**
1. 高円寺→東中野→中井→高田馬場→新宿 **3回**

4番目と5番目が入れ替わりました。
では次に金額でソートしてみます。

## 乗車券の安い順にソートしてみる

でも、ちょっと待ってください。
金額は Price 要素の中から見つける必要があります。

[経路探索のレスポンス](http://docs.ekispert.com/v1/api/search/course/extreme.html#response)

また、乗車券は FareSummary なので ResultSet.Course.Price.FareSummary.Oneway としたいところなのですが、Price は配列になっていて、何番目に FareSummary があるか分かりません。
比較的新しいブラウザであれば indexOf を使う手もありますが、今回は互換性を考えて使わずに実装してみます。
ちなみに、今回は getFareSummary 関数を用意して金額を取得できるようにしてみました。

## 乗車券の金額を取得する関数を用意する

```Javascript
function getFareSummary(Course) {
    if (Course.Price instanceof Array) {
        for (var i = 0; i < Course.Price.length; i++) {
            if (Course.Price[i].kind == "FareSummary") {
                return parseInt(Course.Price[i].Oneway);
            }
        }
    }
    return 0;
}
```
```Javascript
if (list.ResultSet.Course instanceof Array) {
    var buffer = new Array();
    for (var i = 0; i < list.ResultSet.Course.length; i++) {
        buffer.push(getFareSummary(list.ResultSet.Course[i]));
    }
    alert(buffer.join(","));
}
```

まずはソート前の金額を確認です。

1. 高円寺→新宿 **160円**
1. 高円寺→中野(東京都)→高田馬場→新宿 **430円**
1. 高円寺→東中野→新宿 **340円**
1. 高円寺→東中野→中井→高田馬場→新宿 **610円**
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿 **440円**

また、この関数を利用してソートを実装していきます。

```Javascript
if (list.ResultSet.Course instanceof Array) {
    list.ResultSet.Course.sort(function (a, b) {
        if (getFareSummary(a) > getFareSummary(b)) return 1;
        if (getFareSummary(a) < getFareSummary(b)) return -1;
        return 0;
    });
    var buffer = new Array();
    for (var i = 0; i < list.ResultSet.Course.length; i++) {
        buffer.push(getFareSummary(list.ResultSet.Course[i]));
    }
    alert(buffer.join(","));
}
```

そして、金額順のソート結果は下記になりました。

1. 高円寺→新宿 **160円**
1. 高円寺→東中野→新宿 **340円**
1. 高円寺→中野(東京都)→高田馬場→新宿 **430円**
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿 **440円**
1. 高円寺→東中野→中井→高田馬場→新宿 **610円**

## 複合の条件でソートしてみる

今度は所要時間も考慮してソートしてみることにします。
まずは、所要時間を求める関数を用意します。

```Javascript
function getTotalTime(Course) {
    return parseInt(Course.Route.timeOnBoard) + parseInt(Course.Route.timeWalk) + parseInt(Course.Route.timeOther);
}
```

この関数を使って所要時間、金額、乗り換え回数を算出すると下記になります。

1. 高円寺→新宿 **12分** **160円** **0回**
1. 高円寺→中野(東京都)→高田馬場→新宿 **21分** **430円** **1回**
1. 高円寺→東中野→新宿 **26分** **340円** **1回**
1. 高円寺→東中野→中井→高田馬場→新宿 **32分** **610円** **3回**
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿 **31分** **440円** **2回**

では、今まで行ってきたソートをまとめます。

* まずは乗車券が安い順にソート
* 金額が同じだった場合は所要時間の短い順にソート
* 金額も所要時間も同じだった場合は乗り換え回数の少ない順にソート

そして、ソート部分はこちらです。

```Javascript
list.ResultSet.Course.sort(function (a, b) {
    if (getFareSummary(a) > getFareSummary(b) || getFareSummary(a) == getFareSummary(b) && getTotalTime(a) > getTotalTime(b) || getFareSummary(a) == getFareSummary(b) && getTotalTime(a) == getTotalTime(b) && a.Route.transferCount > b.Route.transferCount) return 1;
    if (getFareSummary(a) < getFareSummary(b) || getFareSummary(a) == getFareSummary(b) && getTotalTime(a) < getTotalTime(b) || getFareSummary(a) == getFareSummary(b) && getTotalTime(a) == getTotalTime(b) && a.Route.transferCount < b.Route.transferCount) return -1;
    return 0;
});
```

これを実行すると、きれいに並びました。

1. 高円寺→新宿 **12分** **160円** **0回**
1. 高円寺→東中野→新宿 **26分** **340円** **1回**
1. 高円寺→中野(東京都)→高田馬場→新宿 **21分** **430円** **1回**
1. 高円寺→東中野→中野坂上→新宿(東京メトロ)→新宿 **31分** **440円** **2回**
1. 高円寺→東中野→中井→高田馬場→新宿 **32分** **610円** **3回**

# まとめ
どうでしたか？
結構簡単に実装出来たと思います。
また、特急券を考慮したり、距離を考慮したり、複数の項目を組み合わせてソートしたりも出来ますし、駅すぱあと以外でも sort が使えることが分かっていただけたのではないでしょうか。