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

回答編集履歴

5

ちょっと修正

2018/12/28 04:37

投稿

miyabi-sun
miyabi-sun

スコア21553

answer CHANGED
@@ -36,6 +36,11 @@
36
36
  shopIds.forEach(id =>
37
37
  shops.find(it => it.id === id).isOpen = false
38
38
  );
39
+
40
+ // あるか無いか分からない場面だと先にfilter使うんだけど、ちょっと冗長かなぁ?
41
+ shopIds
42
+ .filter(id => shops.some(it => it.id === id))
43
+ .forEach(id => shops.find(it => it.id === id).isOpen = false)
39
44
  ```
40
45
 
41
46
  逆にshopsを使えばこのようなコードになるでしょう。
@@ -50,6 +55,11 @@
50
55
  // 1: {id: 2, name: "テラサカバ", isOpen: false}
51
56
  // 2: {id: 3, name: "テラ民", isOpen: true}
52
57
  // 3: {id: 4, name: "テラ木屋", isOpen: true}
58
+
59
+ // こちらもfilter版、かなりシンプルでスマート!
60
+ shops
61
+ .filter(it => shopIds.includes(it.id))
62
+ .forEach(it => it.isOpen = false)
53
63
  ```
54
64
 
55
65
  ---

4

コードの修正

2018/12/28 04:37

投稿

miyabi-sun
miyabi-sun

スコア21553

answer CHANGED
@@ -64,7 +64,7 @@
64
64
  ```JavaScript
65
65
  const initialisedShops = shops.map(it => ({
66
66
  ...it, isOpen: shopIds.includes(it.id) ? false : it.isOpen
67
- });
67
+ }));
68
68
  console.log(initialisedShops);
69
69
  // (4) [{…}, {…}, {…}, {…}]
70
70
  // 0: {id: 1, name: "テラ貴族", isOpen: false}

3

校生

2018/12/28 04:33

投稿

miyabi-sun
miyabi-sun

スコア21553

answer CHANGED
@@ -1,17 +1,22 @@
1
- constで作ったオブジェクトに対して破壊的操作で値をいじるのはあまり良くないのですが…
1
+ constで作ったオブジェクトに対して破壊的操作で値をいじるのはあまり良くありません。
2
- まぁいいや、こういう2つの配列を使う場合はどちらを起点にするかでコードの長さが変わります。
3
- この際、どちらが短両方書いてみてしっくり来る方を選びしょう
2
+ う訳で両方のケースで
4
3
 
4
+ 今回の質問文には書かれてませんが、
5
+ 多分この`shopIds`は何らかの事情によりWebサイト上で一時的に準備中にしたいという目的で定義された変数だろうと推測されます。
6
+ なのでそれ想定で書いてます。
7
+
8
+ ---
9
+
10
+ プロパティの値に代入はオブジェクトの破壊的な操作になります。
11
+ 今回のような破壊的操作を伴う場合、戻り値は不要なのでmapは使わずforEachを使うようにしてください。
12
+ mapを使うと未来の貴方や、他のメンバーは「戻り値を使って何かしたいんだ」と勘違いする要因になるので決して使わないでください。
13
+
14
+ また、こういう2つの配列を使う場合はどちらを起点にするかでコードの長さが変わります。
15
+ 両方書いてみてしっくり来る方を選びましょう。
16
+
5
17
  shopIdsを先に使うとこんな感じのコードになります。
6
18
 
7
19
  ```JavaScript
8
- const shopIds = [1, 2];
9
- const shops = [
10
- { id: 1, name: "テラ貴族", isOpen: true},
11
- { id: 2, name: "テラサカバ", isOpen: true},
12
- { id: 3, name: "テラ民", isOpen: true},
13
- { id: 4, name: "テラ木屋", isOpen: true},
14
- ];
15
20
  shopIds.forEach(id =>
16
21
  (shops.find(it => it.id === id) || {}).isOpen = false
17
22
  );
@@ -29,22 +34,13 @@
29
34
 
30
35
  ```JavaScript
31
36
  shopIds.forEach(id =>
32
- shops
33
- .find(it => it.id === id)
37
+ shops.find(it => it.id === id).isOpen = false
34
- .isOpen = false
35
38
  );
36
39
  ```
37
40
 
38
41
  逆にshopsを使えばこのようなコードになるでしょう。
39
42
 
40
43
  ```JavaScript
41
- const shopIds = [1, 2];
42
- const shops = [
43
- { id: 1, name: "テラ貴族", isOpen: true},
44
- { id: 2, name: "テラサカバ", isOpen: true},
45
- { id: 3, name: "テラ民", isOpen: true},
46
- { id: 4, name: "テラ木屋", isOpen: true},
47
- ];
48
44
  shops.forEach(it => {
49
45
  if (shopIds.includes(it.id)) it.isOpen = false
50
46
  })
@@ -59,16 +55,13 @@
59
55
  ---
60
56
 
61
57
  オブジェクトの破壊的操作を避け、コピーする想定でいくならこんな感じになります。
58
+ JavaScriptのプロパティ値に代入する方法は破壊的操作なので使えません。
62
- どの道ワンライナで書けまのでこちらのが良いでしょう
59
+ mapとシャロコピを併用式になります
63
60
 
61
+ shopIdsを主軸にすると変更+変更してないショップ一覧にたどり着くのが困難になりますので、
62
+ shops.mapを主軸にするのが適切でしょう。
63
+
64
64
  ```JavaScript
65
- const shopIds = [1, 2];
66
- const shops = [
67
- { id: 1, name: "テラ貴族", isOpen: true},
68
- { id: 2, name: "テラサカバ", isOpen: true},
69
- { id: 3, name: "テラ民", isOpen: true},
70
- { id: 4, name: "テラ木屋", isOpen: true},
71
- ];
72
65
  const initialisedShops = shops.map(it => ({
73
66
  ...it, isOpen: shopIds.includes(it.id) ? false : it.isOpen
74
67
  });

2

ツッコミをツッコミの位置へ移動

2018/12/28 03:15

投稿

miyabi-sun
miyabi-sun

スコア21553

answer CHANGED
@@ -1,14 +1,3 @@
1
- > 配列shopIdsに格納されたidを持つshopの**isOpenフラグをfalseに書き換える**プログラムを書きました。
2
-
3
- ふんふん……
4
-
5
- > `shop.isOpen = true;`
6
-
7
- 書けてないやん
8
-
9
- ---
10
-
11
- さて本題、
12
1
  constで作ったオブジェクトに対して破壊的操作で値をいじるのはあまり良くないのですが…
13
2
  まぁいいや、こういう2つの配列を使う場合はどちらを起点にするかでコードの長さが変わります。
14
3
  この際、どちらが短いか両方書いてみてしっくり来る方を選びましょう。

1

良いコードをひらめいたので追記

2018/12/28 02:55

投稿

miyabi-sun
miyabi-sun

スコア21553

answer CHANGED
@@ -10,8 +10,11 @@
10
10
 
11
11
  さて本題、
12
12
  constで作ったオブジェクトに対して破壊的操作で値をいじるのはあまり良くないのですが…
13
- まぁいいや、ワンライナーで書けばこうすか
13
+ まぁいいや、こういう2つの配列を使う場合はどちらを起点にでコードの長さが変わります
14
+ この際、どちらが短いか両方書いてみてしっくり来る方を選びましょう。
14
15
 
16
+ shopIdsを先に使うとこんな感じのコードになります。
17
+
15
18
  ```JavaScript
16
19
  const shopIds = [1, 2];
17
20
  const shops = [
@@ -43,10 +46,31 @@
43
46
  );
44
47
  ```
45
48
 
49
+ 逆にshopsを使えばこのようなコードになるでしょう。
50
+
51
+ ```JavaScript
52
+ const shopIds = [1, 2];
53
+ const shops = [
54
+ { id: 1, name: "テラ貴族", isOpen: true},
55
+ { id: 2, name: "テラサカバ", isOpen: true},
56
+ { id: 3, name: "テラ民", isOpen: true},
57
+ { id: 4, name: "テラ木屋", isOpen: true},
58
+ ];
59
+ shops.forEach(it => {
60
+ if (shopIds.includes(it.id)) it.isOpen = false
61
+ })
62
+ console.log(shops);
63
+ // (4) [{…}, {…}, {…}, {…}]
64
+ // 0: {id: 1, name: "テラ貴族", isOpen: false}
65
+ // 1: {id: 2, name: "テラサカバ", isOpen: false}
66
+ // 2: {id: 3, name: "テラ民", isOpen: true}
67
+ // 3: {id: 4, name: "テラ木屋", isOpen: true}
68
+ ```
69
+
46
70
  ---
47
71
 
48
72
  オブジェクトの破壊的操作を避け、コピーする想定でいくならこんな感じになります。
49
- ちらからいってもワンライナーです
73
+ の道ワンライナーで書けまのでこちらの方が良いでしょう
50
74
 
51
75
  ```JavaScript
52
76
  const shopIds = [1, 2];
@@ -56,9 +80,9 @@
56
80
  { id: 3, name: "テラ民", isOpen: true},
57
81
  { id: 4, name: "テラ木屋", isOpen: true},
58
82
  ];
59
- const initialisedShops = shops.map(it =>
83
+ const initialisedShops = shops.map(it => ({
60
- shopIds.includes(it.id) ? {...it, isOpen: false} : {...it}
84
+ ...it, isOpen: shopIds.includes(it.id) ? false : it.isOpen
61
- );
85
+ });
62
86
  console.log(initialisedShops);
63
87
  // (4) [{…}, {…}, {…}, {…}]
64
88
  // 0: {id: 1, name: "テラ貴族", isOpen: false}