コード
シャローコピーで十分なような。
JavaScript
1'use strict';
2
3const payload = [
4 {id: '001', score: 100},
5 {id: '001', score: 40},
6 {id: '100', score: 132},
7 {id: '100', score: 482}
8];
9
10const state = {
11 '001': [
12 {id: '001', score: 142},
13 {id: '001', score: 112}
14 ],
15 '010': [
16 {id: '010', score: 142},
17 {id: '010', score: 112}
18 ]
19}
20
21for (let data of payload) {
22 const id = data.id;
23 data = Object.assign({}, data); // シャローコピー
24
25 if (!Object.prototype.hasOwnProperty.call(state, id)) {
26 state[id] = [data];
27 } else {
28 state[id].push(data);
29 }
30}
31
32var expectedResults = {
33 '100': [
34 { id: '100', score: 132 },
35 { id: '100', score: 482 }
36 ],
37
38 '001': [
39 { id: '001', score: 142 },
40 { id: '001', score: 112 },
41 { id: '001', score: 100 },
42 { id: '001', score: 40 }
43 ],
44
45 '010': [
46 { id: '010', score: 142 },
47 { id: '010', score: 112 }
48 ]
49};
50
51console.log(JSON.stringify(state) === JSON.stringify(expectedResults)); // true
52console.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}]}
副作用がないというか、参照透過性?のある純粋関数を作りたいのです。
JavaScript
1'use strict';
2const payload = [
3 {id: '001', score: 100},
4 {id: '001', score: 40},
5 {id: '100', score: 132},
6 {id: '100', score: 482}
7];
8
9const state = {
10 '001': [
11 {id: '001', score: 142},
12 {id: '001', score: 112}
13 ],
14 '010': [
15 {id: '010', score: 142},
16 {id: '010', score: 112}
17 ]
18};
19
20var expectedResults = {
21 '100': [
22 { id: '100', score: 132 },
23 { id: '100', score: 482 }
24 ],
25
26 '001': [
27 { id: '001', score: 142 },
28 { id: '001', score: 112 },
29 { id: '001', score: 100 },
30 { id: '001', score: 40 }
31 ],
32
33 '010': [
34 { id: '010', score: 142 },
35 { id: '010', score: 112 }
36 ]
37};
38
39function sample (payload, state) {
40 const hasOwnProperty = Object.prototype.hasOwnProperty;
41 const results = JSON.parse(JSON.stringify(state));
42
43 for (let data of payload) {
44 const id = data.id;
45 data = Object.assign({}, data);
46
47 if (!hasOwnProperty.call(state, id)) {
48 results[id] = [data];
49 } else {
50 results[id].push(data);
51 }
52 }
53
54 return results;
55}
56
57const results = sample(payload, state);
58
59console.log(JSON.stringify(state) === JSON.stringify(expectedResults)); // true
60console.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}]}
Deep Copy
//(1)Deep Copyするには?(ライブラリで解決する方法は既に把握済みですが、ライブラリを使わない場合はどう書くのか?
プリミティブ値の集合なら、
JavaScript
1JSON.parse(JSON.stringify(object));
そうでないなら、Object.assign
もしくは Object.assign
の互換コードを再帰処理して下さい。
完全な deep copy ではなく、変数 state
特化のコードで良ければ、次のように書けます。
JavaScript
1const state = {
2 '001': [
3 {id: '001', score: 142},
4 {id: '001', score: 112}
5 ],
6 '010': [
7 {id: '010', score: 142},
8 {id: '010', score: 112}
9 ]
10};
11
12const stateClone = Object.entries(state).reduce((state, entry) => {
13 state[entry[0]] = entry[1].map(Object.assign.bind(null, {}));
14 return state;
15}, state);
16
17console.log(JSON.stringify(state) === JSON.stringify(stateClone)); // true
Re: hayatomo さん
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/08/24 14:09
2017/08/24 14:10
2017/08/24 14:23 編集
2017/08/25 01:19
退会済みユーザー
2017/08/25 01:44