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

回答編集履歴

2

stateClone

2017/08/24 14:34

投稿

think49
think49

スコア18194

answer CHANGED
@@ -137,4 +137,26 @@
137
137
 
138
138
  - [deep-copy-object.js: オブジェクトをディープコピー](https://gist.github.com/think49/96e8fc064b917287cadb1dfacc39695c)
139
139
 
140
+ 完全な deep copy ではなく、変数 `state` 特化のコードで良ければ、次のように書けます。
141
+
142
+ ```JavaScript
143
+ const state = {
144
+ '001': [
145
+ {id: '001', score: 142},
146
+ {id: '001', score: 112}
147
+ ],
148
+ '010': [
149
+ {id: '010', score: 142},
150
+ {id: '010', score: 112}
151
+ ]
152
+ };
153
+
154
+ const stateClone = Object.entries(state).reduce((state, entry) => {
155
+ state[entry[0]] = entry[1].map(Object.assign.bind(null, {}));
156
+ return state;
157
+ }, state);
158
+
159
+ console.log(JSON.stringify(state) === JSON.stringify(stateClone)); // true
160
+ ```
161
+
140
162
  Re: hayatomo さん

1

参照透過性

2017/08/24 14:34

投稿

think49
think49

スコア18194

answer CHANGED
@@ -1,3 +1,5 @@
1
+ ### コード
2
+
1
3
  シャローコピーで十分なような。
2
4
 
3
5
  ```JavaScript
@@ -55,6 +57,74 @@
55
57
  console.log(JSON.stringify(state)); // {"100":[{"id":"100","score":132},{"id":"100","score":482}],"001":[{"id":"001","score":142},{"id":"001","score":112},{"id":"001","score":100},{"id":"001","score":40}],"010":[{"id":"010","score":142},{"id":"010","score":112}]}
56
58
  ```
57
59
 
60
+ > 副作用がないというか、参照透過性?のある純粋関数を作りたいのです。
61
+
62
+
63
+ ```JavaScript
64
+ 'use strict';
65
+ const payload = [
66
+ {id: '001', score: 100},
67
+ {id: '001', score: 40},
68
+ {id: '100', score: 132},
69
+ {id: '100', score: 482}
70
+ ];
71
+
72
+ const state = {
73
+ '001': [
74
+ {id: '001', score: 142},
75
+ {id: '001', score: 112}
76
+ ],
77
+ '010': [
78
+ {id: '010', score: 142},
79
+ {id: '010', score: 112}
80
+ ]
81
+ };
82
+
83
+ var expectedResults = {
84
+ '100': [
85
+ { id: '100', score: 132 },
86
+ { id: '100', score: 482 }
87
+ ],
88
+
89
+ '001': [
90
+ { id: '001', score: 142 },
91
+ { id: '001', score: 112 },
92
+ { id: '001', score: 100 },
93
+ { id: '001', score: 40 }
94
+ ],
95
+
96
+ '010': [
97
+ { id: '010', score: 142 },
98
+ { id: '010', score: 112 }
99
+ ]
100
+ };
101
+
102
+ function sample (payload, state) {
103
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
104
+ const results = JSON.parse(JSON.stringify(state));
105
+
106
+ for (let data of payload) {
107
+ const id = data.id;
108
+ data = Object.assign({}, data);
109
+
110
+ if (!hasOwnProperty.call(state, id)) {
111
+ results[id] = [data];
112
+ } else {
113
+ results[id].push(data);
114
+ }
115
+ }
116
+
117
+ return results;
118
+ }
119
+
120
+ const results = sample(payload, state);
121
+
122
+ console.log(JSON.stringify(state) === JSON.stringify(expectedResults)); // true
123
+ console.log(JSON.stringify(state)); // {"100":[{"id":"100","score":132},{"id":"100","score":482}],"001":[{"id":"001","score":142},{"id":"001","score":112},{"id":"001","score":100},{"id":"001","score":40}],"010":[{"id":"010","score":142},{"id":"010","score":112}]}
124
+ ```
125
+
126
+ ### Deep Copy
127
+
58
128
  > //(1)Deep Copyするには?(ライブラリで解決する方法は既に把握済みですが、ライブラリを使わない場合はどう書くのか?
59
129
 
60
130
  プリミティブ値の集合なら、