JavascriptでJSON

JavascriptでJSON:


はじめに

JavascriptでJSONを扱う機会が多いのでまとめてみます。mapとかreduceとかそろそろ使いこなせるようになりたいです。


前提

扱うJSONは下のような感じにしました。気分です。最近iPod卒業して以下の3つを品定め中だからです。ランキングは一部抜粋、今Apple Musicに傾きつつあるので、他のやつのランキングはスキップで。まあだいたい同じですし。

var sample = { 
    Music_Services:[ 
        { 
            Service: "Apple Music", 
            Company: "Apple", 
            Top_Song_Ranking:{ 
                observation_date: "2019-02-09", 
                ranking:[ 
                    { 
                        artist: "あいみょん", 
                        song: "マリーゴールド", 
                        rank: 1 
                    }, 
                    { 
                        artist: "ONE OK ROCK", 
                        song: "Stand Out Fit In", 
                        rank: 2 
                    }, 
                    { 
                        artist: "あいみょん", 
                        song: "今夜このまま", 
                        rank: 3 
                    }, 
                    { 
                        artist: "エド・シーラン", 
                        song: "Shape of You", 
                        rank: 7 
                    }, 
                    { 
                        artist: "あいみょん", 
                        song: "愛を伝えたいだとか", 
                        rank: 9 
                    } 
                ] 
            } 
        }, 
        { 
            Service: "Google Play Music", 
            Company: "Google", 
            Top_Song_Ranking: null 
        }, 
        { 
            Service: "Spotify", 
            Company: "Spotify AB", 
            Top_Song_Ranking: null 
        } 
    ] 
} 
* データ構造は適当に作ったものでApple MusicのAPI定義とかに合わせたりしてません。


参照


レコード参照

「音楽サービスのどんなデータ入ってるのかザーッと見たい」

sample["Music_Services"].forEach((item) => { 
    console.log(item) 
}) 


{ Service: 'Apple Music', 
  Company: 'Apple', 
  Top_Song_Ranking:  
   { observation_date: '2019-02-09', 
     ranking: [ [Object], [Object], [Object], [Object], [Object] ] } } 
{ Service: 'Google Play Music', 
  Company: 'Google', 
  Top_Song_Ranking: null } 
{ Service: 'Spotify', 
  Company: 'Spotify AB', 
  Top_Song_Ranking: null } 
[Object]の中身表示したかったらconsole.log(JSON.stringify(item)) にすれば見れますね。


プロパティ参照

「一覧だと見づらいからどんな属性があるかだけ見たい」

var firstService = sample["Music_Services"][0] 
Object.keys(firstService).forEach((data) => { 
  console.log(data); 
}) 


Service 
Company 
Top_Song_Ranking 
「もっと深い属性が見たい」

Object.keys(firstService["Top_Song_Ranking"]).forEach((data) => { 
  console.log(data); 
}) 
console.log("====") 
 
var firstSong = firstService["Top_Song_Ranking"]["ranking"][0] 
Object.keys(firstSong).forEach((data) => { 
  console.log(data); 
}) 


observation_date 
ranking 
==== 
artist 
song 
rank 
基本的に1つ目のレコードだけサンプル的にとってきて中を覗く感じです。レコードによってプロパティに過不足ある場合とかは対象外で。


検索


単一検索

「Apple Musicの情報だけ欲しい」

const AppleMusic = sample["Music_Services"].find((item, index) => { 
    return (item.Service === "Apple Music") 
}) 
/*こっちでもおなじ 
const AppleMusic = sample["Music_Services"].find((item, index) => { 
    if(item.Service === "Apple Music") return true 
}) 
*/ 
 
console.log(AppleMusic) 


{ Service: 'Apple Music', 
  Company: 'Apple', 
  Top_Song_Ranking:  
   { observation_date: '2019-02-09', 
     ranking: [ [Object], [Object], [Object], [Object], [Object] ] } } 
ここからはApple Musicしか眼中に入れません。

なので、変数 "AppleMusic"を使いまわします。


複数検索

「あいみょんの曲ってどんぐらいランキング入ってるんだろ」

const Aimyon_Songs = AppleMusic["Top_Song_Ranking"]["ranking"].filter((item, index) => { 
    return (item.artist === "あいみょん") 
}) 
 
console.log(Aimyon_Songs) 


[ { artist: 'あいみょん', song: 'マリーゴールド', rank: 1 }, 
  { artist: 'あいみょん', song: '今夜このまま', rank: 3 }, 
  { artist: 'あいみょん', song: '愛を伝えたいだとか', rank: 9 } ] 
*本当は他にももっと入ってますよ

「英語タイトルの曲どんくらいランキング入ってるんだろ」

const English_Titles = AppleMusic["Top_Song_Ranking"]["ranking"].filter((item, index) => { 
    return (item.song.match(/[a-zA-Z]/)) 
}) 
 
console.log(English_Titles) 


[ { artist: 'ONE OK ROCK', song: 'Stand Out Fit In', rank: 2 }, 
  { artist: 'エド・シーラン', song: 'Shape of You', rank: 7 } ] 
*おまけ

filterは複数検索の時ですね。findも兼ねますが、なんとなく使い分けたいなと。


制限

「曲名だけ一覧でバーっと見たい」

const song_names = AppleMusic["Top_Song_Ranking"]["ranking"].map(x => x["song"]) 
console.log(song_names) 


[ 'マリーゴールド', 
  'Stand Out Fit In', 
  '今夜このまま', 
  'Shape of You', 
  '愛を伝えたいだとか' ] 
mapって主にこういうときに使うイメージですね。他にもあるかな。


集約

「結局ランキングにどういうアーティストが何曲ずつくらい入ってるんだろ」

const summary = AppleMusic["Top_Song_Ranking"]["ranking"].reduce((accum, current)=> { 
    //同じアーティスト名がaccumの中にあるか検索 
    const element = accum.find((item) => {return item.artist === current.artist}); 
    //あったらカウントだけする 
    if(element){ element.count ++} 
    //なかったらaccumに追加してあげる 
    else{ 
        accum.push({ 
            artist: current.artist, 
            count: 1 
        }); 
    } 
    return accum 
}, []); 
 
console.log(summary) 


[ { artist: 'あいみょん', count: 3 }, 
  { artist: 'ONE OK ROCK', count: 1 }, 
  { artist: 'エド・シーラン', count: 1 } ] 
reduceは集約するときに使う感じですね。forEachで足していくほうがわかりやすいんですけどreduceが使えたらかっこいいなと。まだまだ慣れません。


おわりに

reduceはやはり小難しい。あいみょんすごい。もう少し追記していきたいと思っているところです。



コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)