6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavascriptでJSON

Last updated at Posted at 2019-02-09

はじめに

 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はやはり小難しい。あいみょんすごい。もう少し追記していきたいと思っているところです。


6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?