JSONの値に至るまでのキーの列を調べる


# 複雑なJSONになると、値に至るまでのキーを調べるのってちょっと面倒です。

+ 辞書の中が辞書で、その中が配列で...とかちょい面倒です。

# JSONの値ごとに、値にたどり着くためのキーの列を全て表示します。

## プログラム

+ Qiitaの投稿リストを取得するJSON-APIを解読してみます。
+ もちろん階層も辿ります。


```javascript:trace.js
'use strict'

var trace = (function(root_object) {

	var stack = [];

	function instance_type(value) {
		if (value instanceof Array) return "array";
		if (value instanceof Object) return "object";
		return typeof value;
	}

	function trace(object) {
		var it = instance_type(object);
		if (it === 'object' || it === 'array') {
			for (var i in object) {
				var qk = (it === 'array' ? '[' + i + ']' : '.' + i );
				stack.push(qk);
				if (instance_type(object[i]) !== 'object' && instance_type(object[i]) !== 'array') {
					var qs = (typeof object[i] === 'string' ? '"' : '');
					var value = object[i];
					console.log('json_root' + stack.join('') + " = " + qs + value + qs);
				} else {
					trace(object[i]);
				}
				stack.pop();
			}
		}
	}

	trace(root_object);
});


// http://qiita.com/n0bisuke/items/788dc4379fd57e8453a3 から引用
let http = require('http');
const URL = 'http://qiita.com/qoAop/items.json'; // 私の投稿一覧を取得するURL

http.get(URL, (res) => {
	let body = '';
	res.setEncoding('utf8');
	res.on('data', (chunk) => {
		body += chunk;
	});
	res.on('end', (res) => {
		res = JSON.parse(body);
		trace(res)
	});
}).on('error', (e) => {
	console.log(e.message); //エラー時
});

```

## 実行

+ node.jsで実行してみてください。

```shell:node.js
% node trace.js > trace.txt
```

## 結果

+ JSONのメンバと結果一覧です。
+ 階層構造じゃなくて値ごとにすべてのキーをフラットに表示します。
+ どこが配列でどこが辞書かがざっくりわかりますよね？

```javascript:trace.txt
json_root[0].id = 381148
json_root[0].uuid = "e4509bf1419ac8f6cb72"
json_root[0].user.id = 51116
json_root[0].user.url_name = "qoAop"
json_root[0].user.profile_image_url = "https://avatars.githubusercontent.com/u/6275967?v=3"
json_root[0].title = "JSONの値とキー文字列もあわせてすべて見る"
json_root[0].created_at = "2016-03-29 01:12:59 +0900"
json_root[0].updated_at = "2016-03-29 01:12:59 +0900"
json_root[0].created_at_in_words = "about 6 hours"
json_root[0].updated_at_in_words = "about 6 hours"
json_root[0].tags[0].name = "JavaScript"
json_root[0].tags[0].url_name = "javascript"
json_root[0].tags[0].icon_url = "https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/58f69837141ae3efa0c530ed53de128cacb49b66/medium.jpg?1421232838"
json_root[0].tags[1].name = "Node.js"
json_root[0].tags[1].url_name = "node.js"
json_root[0].tags[1].icon_url = "https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/99671b12d7d2688f35c262552f16c7cc9d10b873/medium.jpg?1390767445"
json_root[0].tags[2].name = "JSON"
json_root[0].tags[2].url_name = "json"
json_root[0].tags[2].icon_url = "https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/c01990c29ce345a67f3b5e85102dfd84276b8e95/medium.jpg?1387911385"
json_root[0].stock_count = 0
〜〜中略〜〜
json_root[18].url = "http://qiita.com/qoAop/items/0e059fd217573d6ef11b"
json_root[18].created_at_as_seconds = 1453539116
json_root[18].tweet = false
json_root[18].private = false
json_root[19].id = 362849
json_root[19].uuid = "fe9f106a00d1f4ae915b"
json_root[19].user.id = 51116
json_root[19].user.url_name = "qoAop"
json_root[19].user.profile_image_url = "https://avatars.githubusercontent.com/u/6275967?v=3"
json_root[19].title = "Swiftはじめたい...その１０ 特殊変数とか参照渡しとか、ジェネリクスとか..."
json_root[19].created_at = "2016-01-20 23:58:14 +0900"
json_root[19].updated_at = "2016-01-21 00:01:07 +0900"
json_root[19].created_at_in_words = "2 months"
json_root[19].updated_at_in_words = "2 months"
json_root[19].tags[0].name = "Xcode"
json_root[19].tags[0].url_name = "xcode"
json_root[19].tags[0].icon_url = "https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/cfd750c29b80301e5979124db930d303143c5529/medium.jpg?1436113213"
json_root[19].tags[1].name = "Swift"
json_root[19].tags[1].url_name = "swift"
json_root[19].tags[1].icon_url = "https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/8924010780db484a83145542a3e49c6c2084ecb7/medium.jpg?1401738498"
json_root[19].stock_count = 10
json_root[19].comment_count = 0
json_root[19].url = "http://qiita.com/qoAop/items/fe9f106a00d1f4ae915b"
json_root[19].created_at_as_seconds = 1453301894
json_root[19].tweet = false
json_root[19].private = false
```

## 参考
+ QiitaのAPIを取得するところは取るところは[Node.jsでHTTP GETしてJSONパースするメモ](http://qiita.com/n0bisuke/items/788dc4379fd57e8453a3)を参考にさせていただきました。


# ツッコミ・コメント上等！

+ もっといい手があるよ！とか、ココちがくない？ということがあればコメントよろしくお願いします。