teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

そのコードを書いた理由、new Mapのコード

2016/11/09 11:47

投稿

think49
think49

スコア18194

answer CHANGED
@@ -1,16 +1,18 @@
1
+ ### 要素数が必ず1になる
2
+
1
3
  > ```JavaScript
2
4
  > keys = ["name", "address", "tell" ];
3
5
  > values = ["東京都庁舎", "東京都新宿区歌舞伎町1-7-1", "03-5321-1111"];
4
6
  > ```
5
- >
7
+ >
6
8
  > こうしたい↓
7
- >
9
+ >
8
10
  > ```JavaScript
9
11
  > about = [{"name":"東京都庁舎", "address":"東京都新宿区歌舞伎町1-7-1", "tell":"03-5321-1111"}];
10
12
  > ```
11
13
 
12
14
  その前提条件ですと**配列の要素数が必ず1になる**ので配列を使う意義が見いだせません。
13
- 元となるデータにさらに条件があるのでは…。
15
+ 元となるデータにに条件があるのでは…。
14
16
 
15
17
  ```JavaScript
16
18
  var keys = ["name", "address", "tell" ],
@@ -27,6 +29,8 @@
27
29
  console.log(JSON.stringify(array)); // [{"name":"東京都庁舎","address":"東京都新宿区歌舞伎町1-7-1","tell":"03-5321-1111"}]
28
30
  ```
29
31
 
32
+ ### Array.prototype.map
33
+
30
34
  **(2016/11/09 13:54追記)**
31
35
 
32
36
  追記された条件を元にコードを書き換えました。
@@ -59,4 +63,73 @@
59
63
  console.log(JSON.stringify(about)); // [{"name":"東京都庁舎","address":"東京都新宿区歌舞伎町1-7-1","tell":"03-5321-1111"},{"name":"埼玉県庁舎","address":"埼玉県さいたま市浦和区高砂3-15-1","tell":"048-824-2111"}]
60
64
  ```
61
65
 
66
+ **(2016/11/09 20:47 追記)**
67
+
68
+ > 変な質問なのですが、なぜそのコードにされたのですか。
69
+
70
+ まず、私は「短いコード」よりも「可読性」「保守性」「厳密性」を重視しています。
71
+
72
+ - `for` 文では存在しないプロパティを走査する事がある為、`hasOwnProperty` を入れました
73
+ - `{}` では意図せず `[[Prototype]]` 上のプロパティを拾う事がある為、`Object.create(null)` を使いました
74
+ - テストした結果を確認する為に `JSON.stringify()` を使いました(`console.log` や `console.dir` でも確認可能ですが、出力結果をここに張り付けるなら `JSON.stringify` は重宝します)
75
+ - `Array.prototype.map` の第一引数に関数式を指定するとGCの扱いが微妙かつ、関数呼び出しする度に関数オブジェクトが生成される為、パフォーマンスを考慮してクロージャにコールバック関数を閉じ込めました
76
+
77
+ それぞれに意味があって書いているコードですので私はそれを「必要なもの」と考えています。
78
+ 逆に言えば、例外処理を甘くしてキャッシュする変数を減らせば短く書く事は可能ですが、そういうコードは思わぬところで想定外の動作を引き起こし、混乱を生むので良くないと思ってます。
79
+ 良いコードは想定外の値が与えられたときに動かない、か原因に気が付きやすい設計をしています。
80
+
81
+ 配列を回す手段は主に4つあります。
82
+
83
+ - `while` 文
84
+ - `for` 文
85
+ - `for-of` 文
86
+ - `Array.prototype` 系メソッド
87
+
88
+ 自身の嗜好を重んずるなら私は `for` or `while` 文のネストを採用しますが、この手のコードは敬遠される傾向があるように思います。
89
+ ですので、万人受けするであろう `Array.prototype.map` を採用しました。
90
+ 一通りの手段を熟知している人であれば、どの技術を採用するかは個人の好みだと思います。
91
+ k-s さんにとって `for` 文のネストが読みやすかったのであれば、`for` 文が最も k-s さんに親しみ深い使い慣れたものだったのでしょう。
92
+
93
+ ### new Map (ES6)
94
+
95
+ 完全に私の好みで書いていいのなら私は `Map` を使います。
96
+
97
+ ```JavaScript
98
+ 'use strict';
99
+ var arrayToMap = (function (isArray, Map) {
100
+ return function arrayToMap (array, keys) {
101
+ var results = [];
102
+
103
+ for (var i = 0, l = array.length, values; i < l; ++i) {
104
+ values = array[i];
105
+
106
+ if (isArray(values)) {
107
+ for (var j = 0, m = values.length, entries = []; j < m; ++j) {
108
+ if (values.hasOwnProperty(j) && keys.hasOwnProperty(j)) {
109
+ entries.push([keys[j], values[j]]);
110
+ }
111
+ }
112
+
113
+ results.push(new Map(entries));
114
+ }
115
+ }
116
+
117
+ return results;
118
+ };
119
+ }(Array.isArray, Map));
120
+
121
+ var keys = ['name', 'address', 'tell' ],
122
+ values = [['東京都庁舎', '東京都新宿区歌舞伎町1-7-1', '03-5321-1111'],['埼玉県庁舎', '埼玉県さいたま市浦和区高砂3-15-1', '048-824-2111']],
123
+ about = arrayToMap(values, keys),
124
+ array = [];
125
+
126
+ for (let map of about) {
127
+ array.push([...map]);
128
+ }
129
+ console.log(JSON.stringify(array)); // [[["name","東京都庁舎"],["address","東京都新宿区歌舞伎町1-7-1"],["tell","03-5321-1111"]],[["name","埼玉県庁舎"],["address","埼玉県さいたま市浦和区高砂3-15-1"],["tell","048-824-2111"]]]
130
+ ```
131
+
132
+ 基本的に `new Map` はオブジェクト初期化子の上位互換ですので、値を取りだすときにも扱いやすいです。
133
+ 後々、`JSON` 化する予定があるのなら `Map` からオブジェクト初期化子に変換するコードを書きます。
134
+
62
135
  Re: k-s さん

2

追記された条件を元にコードを書き換え

2016/11/09 11:47

投稿

think49
think49

スコア18194

answer CHANGED
@@ -27,4 +27,36 @@
27
27
  console.log(JSON.stringify(array)); // [{"name":"東京都庁舎","address":"東京都新宿区歌舞伎町1-7-1","tell":"03-5321-1111"}]
28
28
  ```
29
29
 
30
+ **(2016/11/09 13:54追記)**
31
+
32
+ 追記された条件を元にコードを書き換えました。
33
+
34
+ ```JavaScript
35
+ 'use strict';
36
+ var arrayToMap = (function () {
37
+ function mapfn (values) {
38
+ for (var i = 0, l = this.length, obj = Object.create(null); i < l; ++i) {
39
+ if (values.hasOwnProperty(i)) {
40
+ obj[this[i]] = values[i];
41
+ }
42
+ }
43
+
44
+ return obj;
45
+ }
46
+
47
+ return function arrayToMap (array, keys) {
48
+ return array.map(mapfn, keys);
49
+ }
50
+ }());
51
+
52
+ var keys = ['name', 'address', 'tell' ],
53
+ values = [
54
+ ['東京都庁舎', '東京都新宿区歌舞伎町1-7-1', '03-5321-1111'],
55
+ ['埼玉県庁舎', '埼玉県さいたま市浦和区高砂3-15-1', '048-824-2111']
56
+ ];
57
+
58
+ var about = arrayToMap(values, keys);
59
+ console.log(JSON.stringify(about)); // [{"name":"東京都庁舎","address":"東京都新宿区歌舞伎町1-7-1","tell":"03-5321-1111"},{"name":"埼玉県庁舎","address":"埼玉県さいたま市浦和区高砂3-15-1","tell":"048-824-2111"}]
60
+ ```
61
+
30
62
  Re: k-s さん

1

引用文を追記

2016/11/09 04:54

投稿

think49
think49

スコア18194

answer CHANGED
@@ -1,4 +1,15 @@
1
+ > ```JavaScript
2
+ > keys = ["name", "address", "tell" ];
3
+ > values = ["東京都庁舎", "東京都新宿区歌舞伎町1-7-1", "03-5321-1111"];
4
+ > ```
5
+ >
6
+ > こうしたい↓
7
+ >
8
+ > ```JavaScript
9
+ > about = [{"name":"東京都庁舎", "address":"東京都新宿区歌舞伎町1-7-1", "tell":"03-5321-1111"}];
10
+ > ```
11
+
1
- その前提条件ですと配列の要素数が必ず1になるので配列を使う意義が見いだせません。
12
+ その前提条件ですと**配列の要素数が必ず1になる**ので配列を使う意義が見いだせません。
2
13
  元となるデータにさらに条件があるのでは…。
3
14
 
4
15
  ```JavaScript