GoogleTagManagerの多次元配列のデータレイヤーから任意の値を取り出す方法

## 前提

* データレイヤーが次のような構造になっていること

```
<script>
dataLayer = [{
one: {
    detail: [
    {
      id: "1",
    },
    {
      id: "2",
    },
    {
      id: "3",
    },
    ],
  },
two: {
    detail: [
    {
      id: "4",
    },
    {
      id: "5",
    },
    {
      id: "6",
    },
    ],
  },
}];

</script>
```

## したいこと

* オブジェクトのプロパティ（one,two）の部分が複数あるが、このうちoneの中のdetailの中のidの1,2だけを取り出したい
* 任意のページでその取り出したidをトリガーで発火させて、任意のHTMLタグを発行したい

## ポイント

* ドット記法ではなく、ブラケット記法で書く。
* ドット記法では変数が利用できないが、ブラケット記法ではそれができる。

## すること Phase.1 変数

* コンテナ > 変数 > ユーザー定義変数 > 新規 ボタンをクリック
* 名前のない変数 > （何か好きな名前をつける。ここではdl_idsとする）
* 種類を選択 > カスタム JavaScript
* 変数を設定

次のように書く（scriptタグは不要）

```
function(){

	// この配列の中にfor in文を実行したいプロパティ名を入力
	var dL_aryChk = [
		'one',
	];

	// この中に出力結果を入れるので一旦空の配列で作っておく
	var dL_id = [];

	for(var i in dataLayer){
		for(var j = 0; j < dL_aryChk.length; j++){ 
			if(dL_aryChk[j] in dataLayer[i]){ // dataLayer[i] = dataLayer { one }
				var dL_propName = dL_aryChk[j]; // ex: dL_propName = one
				for(var j in dataLayer[i][dL_propName]['detail']){ // ドット記法の場合に入る期待内容 dataLayer[i].one.detail
					dL_id.push(dataLayer[i][dL_propName]['detail'][j].id); // dataLayer[i].one.detail[j].id
				}
			}
		}
	}
	return dL_id; // 返ってくる内容 ["1","2","3"]
}
```

* 変数を保存

なお、ローカル環境で確認したい場合はこれを使って下さい。
開発者ツールを使えばコンソールに配列が返ってきていることが確認できるはずです。

```
<html>
<head>
<script>
dataLayer = [{
one: {
    detail: [
    {
      id: "1",
    },
    {
      id: "2",
    },
    {
      id: "3",
    },
    ],
  },
two: {
    detail: [
    {
      id: "4",
    },
    {
      id: "5",
    },
    {
      id: "6",
    },
    ],
  },
}];
</script>
</head>
<body>

<script type="text/javascript">
window.onload =

function(){

	// この配列の中にfor in文を実行したいプロパティ名を入力
	var dL_aryChk = [
		'one',
	];

	// この中に出力結果を入れるので一旦空の配列で作っておく
	var dL_id = [];

	for(var i in dataLayer){
		for(var j = 0; j < dL_aryChk.length; j++){ 
			if(dL_aryChk[j] in dataLayer[i]){ // dataLayer[i] = dataLayer { one }
				var dL_propName = dL_aryChk[j]; // ex: dL_propName = one
				for(var j in dataLayer[i][dL_propName]['detail']){ // ドット記法の場合に入る期待内容 dataLayer[i].one.detail
					dL_id.push(dataLayer[i][dL_propName]['detail'][j].id); // dataLayer[i].one.detail[j].id
				}
			}
		}
	}
	console.log(dL_id); // 運用の際はこの記述を削除し、returnのコメントアウトを解除すること
//	return dL_id; // 返ってくる内容 ["1","2","3"]
}
</script>
</body>
</html>
```

## すること Phase.2 トリガー

* コンテナ > トリガー > 新規 ボタンをクリック
* 名前のない変数 > （何か好きな名前をつける。ここではid_match_1とする）
* イベントを選択 > ページビュー
* トリガーを設定 > トリガーのタイプ > ページビュー
* 配信するタイミング

次のように設定

dl_ids 正規表現に一致 ^1||2$ （ひとつだけでいいなら dl_ids 等しい 1 でOK）

トリガーを保存

## すること Phase.3 タグ

* コンテナ > タグ > 新規 ボタンをクリック
* 名前のないタグ > （何か好きな名前をつける。ここではdl_tagとする）
* プロダクトを選択 > カスタムHTMLタグ
* タグを設定 （任意のHTMLタグをここに設定する） > document.writeをサポートする にチェック
* 詳細設定 > タグ呼び出しオプション > 1ページにつき1度
* 配信するタイミング > その他 > dl_ids を選択
* タグを保存

## NHK

完

## 追記

もし取り出したい値が固定なのであれば、次のようにドット記法だけで書ける。
こっちならわかりやすくて助かりますよね。
まあそれで要件が達成できないからブラケット記法を使ったわけですけども。。

```
function(){
	var dL_id = [];
	for(var i in dataLayer){
		for(var j in dataLayer[i].one.detail){
			dL_id.push(dataLayer[i].one.detail[j].id);
		}
	}
	return dL_id; // 返ってくる内容 ["1","2","3"]
}
```

## さらに追記

こんな書き方もできたなって

```
function(){
	var dL_id = [];

	for(var i in dataLayer){
		for(var j in dataLayer[i]){
			for(var k in dataLayer[i][j]['detail']){ // dataLayer[i].one.detail
				dL_id.push(dataLayer[i][j]['detail'][k]['id']); // dataLayer[i].one.detail[k].id
			}
		}
	}
	return dL_id; // ["1","2","3"]
}
```

トリガーではなく、カスタムJavaScript内でidの特定を完結させる方法も考えました。
トリガー側では、dL_id 等しい true とかにすれば発火するんじゃない？知らないけど。

```
function (){

	var dL_aryChk = ["1","2"];
	var dL_id = [];
	for(var i in dataLayer){
		for(var j in dataLayer[i]){
			for(var k in dataLayer[i][j]['detail']){
				var target_ids = dataLayer[i][j]['detail'][k]['id'];
				if (dL_aryChk.indexOf(target_ids)){
	 				dL_id.push(target_ids);
				}
			}
		}
	}
	return (dL_id.length > 0) ? true : false;
}
```