##APIデータより抽出したデータを、要素を指定してsort
#変数.sort_by { |変数| (-なら降順)変数['任意の要素'].to_i }
@results.sort_by! { |hash| hash['releaseDate'].to_i }
このように記述することで、指定した要素よりsort機能を利用することができる。
##修正!!
上記コードでは抽出したデータ(2017-07-20
)を年ではソート出来ているものの、月日まではソート出来ていないケースが非常に多かったことを見逃していたため、修正した形が以下のコードになります。
Rubyにおける通常のソートと見た目はあまり変わりません。
ただArray
ではなくHash
のsortになるので、a['key']
とする必要あり。
@results.sort! {|a, b| a['releaseDate'] <=> b['releaseDate'] }
###以下解決に到るまでの道程
APIより抽出したjson配列をそのまま変数に格納。
以下はiTunesの例。
url = "https://itunes.apple.com/search?term=井上陽水&lang=ja_jp&country=JP&media=music&limit=100"
uri = URI.encode(url)
info = URI.parse(uri)
json = Net::HTTP.get(info)
result = JSON.parse(json)
@results = result["results"]
ここで@results
のクラスを確認することで適用できるメソッドを探る。
@results.class
=>Array
配列と出てきたが、実際に入っているデータ構造はhashである為
> {"wrapperType"=>"track", "kind"=>"song", "artistId"=>76112633, "collectionId"=>284457303, "trackId"=>284457304, "artistName"=>"井上陽水", "collectionName"=>"少年時代 - Single", "trackName"=>"少年時代", "collectionCensoredName"=>"少年時代 - Single", "trackCensoredName"=>"少年時代", "artistViewUrl"=>"https://itunes.apple.com/jp/artist/%E4%BA%95%E4%B8%8A%E9%99%BD%E6%B0%B4/76112633?uo=4", "collectionViewUrl"=>"https://itunes.apple.com/jp/album/%E5%B0%91%E5%B9%B4%E6%99%82%E4%BB%A3/284457303?i=284457304&uo=4", "trackViewUrl"=>"https://itunes.apple.com/jp/album/%E5%B0%91%E5%B9%B4%E6%99%82%E4%BB%A3/284457303?i=284457304&uo=4", "previewUrl"=>"https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview62/v4/cc/d0/d2/ccd0d255-51e5-608c-1f30-a33da272aaf9/mzaf_103202930428167730.plus.aac.p.m4a", "artworkUrl30"=>"https://is2-ssl.mzstatic.com/image/thumb/Music/v4/57/97/ff/5797ff38-0680-cd6b-7a0d-29cbc34cf368/source/30x30bb.jpg", "artworkUrl60"=>"https://is2-ssl.mzstatic.com/image/thumb/Music/v4/57/97/ff/5797ff38-0680-cd6b-7a0d-29cbc34cf368/source/60x60bb.jpg", "artworkUrl100"=>"https://is2-ssl.mzstatic.com/image/thumb/Music/v4/57/97/ff/5797ff38-0680-cd6b-7a0d-29cbc34cf368/source/100x100bb.jpg", "collectionPrice"=>500.0, "trackPrice"=>250.0, "releaseDate"=>"1990-09-21T07:00:00Z", "collectionExplicitness"=>"notExplicit", "trackExplicitness"=>"notExplicit", "discCount"=>1, "discNumber"=>1, "trackCount"=>2, "trackNumber"=>1, "trackTimeMillis"=>201027, "country"=>"JPN", "currency"=>"JPY", "primaryGenreName"=>"J-Pop", "isStreamable"=>false}
key
とそれに対応するvalues
より出来ているhash
である。
そこで配列のfirst
メソッドを用いて最初の要素を抽出してclass
を確認すると
@results.first.class
=>Hash
やはりデータが格納されているのはHashクラスである。
Hashであるならばkey
を指定することで要素が取り出せるはずなので
@results.first("releaseDate")
TypeError: no implicit conversion of String into Integer
要素を取り出そうとすると数値に変換出来ないとのエラーが生じる。
これは以前teratailにて質問した際に頂いた回答
@members[:name]
TypeError: no implicit conversion of Symbol into IntegerArray#[]がdelegateでrecordsを通して呼ばれています。
@members.records[:name]と同義です。
Array#[]は引数を暗黙的に数値変換します(to_intという厳密な変換です)。
:nameはto_intできる対象ではないため、このエラーが発生したのだと思います。
よりhash
に対応するメソッドをarray
クラスに用いていたこととなる。
そこでhash
となるfirst
を付与した後にvalues_at
を用いることでデータの抽出に成功。
@results.first.values_at("releaseDate")
=>["1990-09-21T07:00:00Z"]
再び問題となるのが、これをどう利用してsort
に結びつけるか。
@results.sory_by(@results.values_at("releaseDate"))
=>TypeError: no implicit conversion of String into Integer
sort_by
メソッドの引数に先ほど得ることの出来たメソッドをそのまま代入してみるもエラー。
それもそのはず今回はfirst
が付いていない為にhash
に用いていたvalues_at
が使えないことになるから・・?
最終的に参考となったサイトがこちら
SONな配列を、指定の項目でソートをかける、PHPとRuby比較
またteratailより頂いたpluck
メソッドを使用すると
@results.pluck("releaseDate")
=> ["1990-09-21T07:00:00Z", "2017-05-31T07:00:00Z", "1993-07-21T07:00:00Z", "2018-06-08T07:00:00Z", "1984-12-21T08:00:00Z", "2014-12-09T08:00:00Z", "2018-05-23T07:00:00Z", "2017-01-20T08:00:00Z", "2008-07-16T07:00:00Z", "2008-12-10T08:00:00Z", "1984-12-21T08:00:00Z", "1984-12-21T08:00:00Z", "1982-12-05T08:00:00Z", "2008-12-10T08:00:00Z", "2008-07-16T07:00:00Z", "2008-07-16T07:00:00Z", "2008-07-16T07:00:00Z", "2008-12-10T08:00:00Z", "1980-12-05T08:00:00Z", "1984-12-21T08:00:00Z", "2008-12-10T08:00:00Z", "2008-12-10T08:00:00Z", "1986-01-01T08:00:00Z", "1984-12-21T08:00:00Z", "2008-07-16T07:00:00Z", "1990-10-21T07:00:00Z", "2008-07-16T07:00:00Z", "2010-11-17T08:00:00Z", "1987-12-16T08:00:00Z", "1990-10-21T07:00:00Z", "2008-07-16T07:00:00Z", "2008-07-16T07:00:00Z", "1973-12-01T08:00:00Z", "2008-07-16T07:00:00Z", "2008-07-16T07:00:00Z", "1981-11-21T08:00:00Z", "2008-12-10T08:00:00Z", "2010-11-17T08:00:00Z", "1992-11-20T08:00:00Z", "2008-12-10T08:00:00Z", "1976-03-25T08:00:00Z", "1984-12-21T08:00:00Z", "2008-07-16T07:00:00Z", "2008-12-10T08:00:00Z", "2008-07-16T07:00:00Z", "1982-12-05T08:00:00Z", "2008-12-10T08:00:00Z", "2008-07-16T07:00:00Z", "2008-12-10T08:00:00Z", "1976-03-25T08:00:00Z", "2008-07-16T07:00:00Z", "1973-12-01T08:00:00Z", "1990-10-21T07:00:00Z", "2009-04-29T07:00:00Z", "2008-12-10T08:00:00Z", "2001-05-30T07:00:00Z", "2008-12-10T08:00:00Z", "2008-12-10T08:00:00Z", "1984-12-21T08:00:00Z", "1973-12-01T08:00:00Z", "1990-09-21T07:00:00Z", "2008-07-16T07:00:00Z", "2008-12-10T08:00:00Z", "1984-12-21T08:00:00Z", "2002-07-24T07:00:00Z", "1982-12-05T08:00:00Z", "1976-03-25T08:00:00Z", "1984-12-21T08:00:00Z", "1986-01-01T08:00:00Z", "1976-03-25T08:00:00Z", "1979-09-21T07:00:00Z", "1973-12-01T08:00:00Z", "1973-12-01T08:00:00Z", "1992-11-20T08:00:00Z", "1976-03-25T08:00:00Z", "1986-01-01T08:00:00Z", "1982-12-05T08:00:00Z", "1993-09-15T07:00:00Z", "1973-12-01T08:00:00Z", "1979-09-21T07:00:00Z", "1973-12-01T08:00:00Z", "1976-03-25T08:00:00Z", "1976-03-25T08:00:00Z", "1979-09-21T07:00:00Z", "1982-12-05T08:00:00Z", "1973-12-01T08:00:00Z", "1976-03-25T08:00:00Z", "1973-12-01T08:00:00Z", "1982-12-05T08:00:00Z", "1986-01-01T08:00:00Z", "1990-10-21T07:00:00Z", "2010-11-17T08:00:00Z", "1990-10-21T07:00:00Z", "1982-12-05T08:00:00Z", "1976-03-25T08:00:00Z", "1992-11-20T08:00:00Z", "1986-01-01T08:00:00Z", "1990-10-21T07:00:00Z", "1992-11-20T08:00:00Z", "1992-11-20T08:00:00Z"]
該当要素一覧を取得することが出来、またsort
を繋げることもできる。