回答編集履歴

17

テキスト修正

2018/08/11 00:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -1,12 +1,18 @@
1
1
  こんにちは。
2
2
 
3
+ ご質問に
4
+
3
5
 
4
6
 
5
7
  > もっといい感じの書き方があるのではないでしょうか。
6
8
 
7
9
 
8
10
 
9
- いうご質問を 「`if`〜 `else` を使わないで書いてみる」というお題と解釈しての回答になりますが、以下でどうでしょう?
11
+ あります。何もって `いい感じ` のコードとするかは、回答者の私見に委ねられているものと思いますが、私は 「`if`〜 `else` を使わないで書いてみるとどうなりますか?」というお題と解釈したので、それに沿っての回答になります
12
+
13
+
14
+
15
+ [Math.min](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/min) と[Math.max](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/max)を使って、以下でどうでしょう?
10
16
 
11
17
 
12
18
 
@@ -20,9 +26,7 @@
20
26
 
21
27
  ```
22
28
 
23
- ただし、上記はあくまでコードのタイプ量の少なさにこだわった書き方です。
29
+ 上記はあくまでコード量の少なさ、見た目のコードの短さにこだわった書き方です。
24
-
25
-
26
30
 
27
31
  参考までに、stackoverflow にも同様の質問(javascriptではないですが。)
28
32
 

16

テキスト修正

2018/08/11 00:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -1,6 +1,12 @@
1
1
  こんにちは。
2
2
 
3
+
4
+
3
- 以下どうでしょう
5
+ > もっといい感じの書き方があるのはないでしょうか。
6
+
7
+
8
+
9
+ というご質問を 「`if`〜 `else` を使わないで書いてみる」というお題と解釈しての回答になりますが、以下でどうでしょう?
4
10
 
5
11
 
6
12
 
@@ -14,6 +20,48 @@
14
20
 
15
21
  ```
16
22
 
23
+ ただし、上記はあくまでコードのタイプ量の少なさにこだわった書き方です。
24
+
25
+
26
+
27
+ 参考までに、stackoverflow にも同様の質問(javascriptではないですが。)
28
+
29
+
30
+
31
+ - [Where can I find the “clamp” function in .NET?](https://stackoverflow.com/questions/2683442/)
32
+
33
+
34
+
35
+ が挙がっていて、こちらの回答の中にも、`Math.Min` と `Math.Max`を使う、以下の回答があります。
36
+
37
+
38
+
39
+ - [https://stackoverflow.com/a/20443081](https://stackoverflow.com/a/20443081)
40
+
41
+
42
+
43
+ ですが、上記の回答に対する[このコメント](https://stackoverflow.com/questions/2683442/where-can-i-find-the-clamp-function-in-net#comment53011741_20443081)で指摘されているように、一回余分な比較が発生する余地があります。
44
+
45
+
46
+
47
+ 余分な比較を発生させず、かつ一行で書くのであれば、上記の投稿で、質問者さんが最初に
48
+
49
+
50
+
51
+ > I would like to clamp a value x to a range [a, b]:
52
+
53
+
54
+
55
+ > x = (x < a) ? a : ((x > b) ? b : x);
56
+
57
+
58
+
59
+ と書いているように、三項演算子の利用も検討されるとよいかと思います。
60
+
61
+
62
+
63
+ ---
64
+
17
65
  **追記1**
18
66
 
19
67
 

15

テキスト追加

2018/08/10 21:56

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
 
26
26
 
27
- とありましたので、座標上の点を処理するコードのリファクタリングという観点で、以下を追記します。
27
+ とありましたので、座標上の点を処理するコードのリファクタという観点で、以下を追記します。やることは以下です。
28
28
 
29
29
 
30
30
 

14

テキスト追加

2018/08/10 02:57

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -30,7 +30,7 @@
30
30
 
31
31
  - 座標上の点クラス `Point` を作成
32
32
 
33
- - `Point`を拡張して、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成
33
+ - `Point`を拡張して、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成
34
34
 
35
35
  - なお以下では、応用であることを明確にするため、`Point` インスタンスは、xyz軸を持つ3次元空間の点としています。
36
36
 

13

テキスト追加

2018/08/10 02:33

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -1,6 +1,6 @@
1
1
  こんにちは。
2
2
 
3
- 例えば以下でどうでしょう?
3
+ 以下でどうでしょう?
4
4
 
5
5
 
6
6
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  ```
16
16
 
17
- 以下は蛇足です。
17
+ **追記1**
18
18
 
19
19
 
20
20
 
@@ -24,7 +24,19 @@
24
24
 
25
25
 
26
26
 
27
+ とありましたので、座標上の点を処理するコードのリファクタリングという観点で、以下を追記します。
28
+
29
+
30
+
31
+ - 座標上の点クラス `Point` を作成
32
+
27
- とありましたので、座標上の点クラス `Point` 作成し、これを拡張して、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成してみました。なお以下では、応用であることを明確にするため、`Point` インスタンスは、xyz軸を持つ3次元空間の点としています。
33
+ - `Point`をを拡張して、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成
34
+
35
+ - なお以下では、応用であることを明確にするため、`Point` インスタンスは、xyz軸を持つ3次元空間の点としています。
36
+
37
+
38
+
39
+ 上記にそって、作ったコードが以下です。
28
40
 
29
41
 
30
42
 
@@ -110,7 +122,7 @@
110
122
 
111
123
  ---
112
124
 
113
- **追記**
125
+ **追記2**
114
126
 
115
127
 
116
128
 

12

テキスト追加

2018/08/10 02:33

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -250,4 +250,4 @@
250
250
 
251
251
 
252
252
 
253
- アクセサを使う利点としては、上記のコードの最後の2行に書いてあるように、`p2.x = 1000;` と代入しも、 `p2.x` は X座標の上限値の`99`を返すようにできることです。
253
+ アクセサを使う利点としては、上記のコードの最後の2行に書いてあるように、`p2.x = 1000;` と代入したつりでも、 `p2.x` は X座標の上限値の`99`を返すようにできることです。

11

テキスト追加

2018/08/10 02:21

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -14,9 +14,17 @@
14
14
 
15
15
  ```
16
16
 
17
-
17
+ 以下は蛇足です。
18
+
19
+
20
+
18
-
21
+ ご質問の冒頭に、
22
+
23
+ > 座標(x, y)が・・・
24
+
25
+
26
+
19
- 蛇足すが、上ように`Math.min`と`Math.max`を使った例として、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される、3次元空間の点`RestrictedPoint`を作成してみました。
27
+ とありましたので、座標上の点クラス `Point` 作成、これを拡張して、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成してみました。なお以下では、応用であることを明確にするため、`Point` インスタンスは、xyz軸を持つ3次元空間の点としています。
20
28
 
21
29
 
22
30
 

10

テキスト追加

2018/08/10 02:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -174,37 +174,29 @@
174
174
 
175
175
 
176
176
 
177
- get x() {
177
+ get(axis) {
178
-
178
+
179
- const conf = this.constructor.config().x;
179
+ const conf = this.constructor.config()[axis];
180
-
180
+
181
- return Math.min(conf.max, Math.max(conf.min, this._x));
181
+ return Math.min(conf.max, Math.max(conf.min, this[`_${axis}`]));
182
-
182
+
183
- }
183
+ }
184
+
185
+
186
+
187
+ get x() { return this.get('x'); }
184
188
 
185
189
  set x(value) { this._x = value; }
186
190
 
187
191
 
188
192
 
189
- get y() {
190
-
191
- const conf = this.constructor.config().y;
193
+ get y() { return this.get('y'); }
192
-
193
- return Math.min(conf.max, Math.max(conf.min, this._y));
194
-
195
- }
196
194
 
197
195
  set y(value) { this._y = value; }
198
196
 
199
197
 
200
198
 
201
- get z() {
202
-
203
- const conf = this.constructor.config().z;
199
+ get z() { return this.get('z'); }
204
-
205
- return Math.min(conf.max, Math.max(conf.min, this._z));
206
-
207
- }
208
200
 
209
201
  set z(value) { this._z = value; }
210
202
 
@@ -246,8 +238,8 @@
246
238
 
247
239
 
248
240
 
249
- [https://jsfiddle.net/jun68ykt/cs86vtj3/70/](https://jsfiddle.net/jun68ykt/cs86vtj3/70/)
241
+ [https://jsfiddle.net/jun68ykt/cs86vtj3/73/](https://jsfiddle.net/jun68ykt/cs86vtj3/73/)
250
-
251
-
252
-
242
+
243
+
244
+
253
- 上記のコードの最後の2行に書いてあるように、`p2.x = 1000` と代入しても、 `p2.x` は X座標の上限値の`99`を返します。
245
+ アクセサを使う利点としては、上記のコードの最後の2行に書いてあるように、`p2.x = 1000;` と代入しても、 `p2.x` は X座標の上限値の`99`を返すようにできることです

9

テキスト修正

2018/08/10 02:03

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -246,7 +246,7 @@
246
246
 
247
247
 
248
248
 
249
- [https://jsfiddle.net/cs86vtj3/68/](https://jsfiddle.net/cs86vtj3/68/)
249
+ [https://jsfiddle.net/jun68ykt/cs86vtj3/70/](https://jsfiddle.net/jun68ykt/cs86vtj3/70/)
250
250
 
251
251
 
252
252
 

8

テキスト追加

2018/08/10 01:53

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -246,7 +246,7 @@
246
246
 
247
247
 
248
248
 
249
- [https://jsfiddle.net/cs86vtj3/66/](https://jsfiddle.net/cs86vtj3/66/)
249
+ [https://jsfiddle.net/cs86vtj3/68/](https://jsfiddle.net/cs86vtj3/68/)
250
250
 
251
251
 
252
252
 

7

テキスト追加

2018/08/10 01:52

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -246,7 +246,7 @@
246
246
 
247
247
 
248
248
 
249
- [https://jsfiddle.net/cs86vtj3/65/](https://jsfiddle.net/cs86vtj3/65/)
249
+ [https://jsfiddle.net/cs86vtj3/66/](https://jsfiddle.net/cs86vtj3/66/)
250
250
 
251
251
 
252
252
 

6

テキスト追加

2018/08/10 01:40

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -97,3 +97,157 @@
97
97
  以下、上記を試行するサンプルです。
98
98
 
99
99
  [https://jsfiddle.net/jun68ykt/cs86vtj3/15/](https://jsfiddle.net/jun68ykt/cs86vtj3/15/)
100
+
101
+
102
+
103
+ ---
104
+
105
+ **追記**
106
+
107
+
108
+
109
+ もうひとつ蛇足ですが、上記の`RestrictedPoint` の書き方として、アクセサを使う手もありそうです。
110
+
111
+
112
+
113
+ ```javascript
114
+
115
+ class Point {
116
+
117
+ constructor(x=0, y=0, z=0) {
118
+
119
+ this._x = x;
120
+
121
+ this._y = y;
122
+
123
+ this._z = z;
124
+
125
+ }
126
+
127
+
128
+
129
+ get x() { return this._x; }
130
+
131
+ set x(value) { this._x = value; }
132
+
133
+
134
+
135
+ get y() { return this._y; }
136
+
137
+ set y(value) { this._y = value; }
138
+
139
+
140
+
141
+ get z() { return this._z; }
142
+
143
+ set z(value) { this._z = value; }
144
+
145
+
146
+
147
+ toString() {
148
+
149
+ return `(x: ${this.x}, y: ${this.y}, z: ${this.z})`;
150
+
151
+ }
152
+
153
+ }
154
+
155
+
156
+
157
+ class RestrictedPoint extends Point {
158
+
159
+
160
+
161
+ static config() {
162
+
163
+ return {
164
+
165
+ x: { min: 0, max: 99 }, // X座標は0以上99以下
166
+
167
+ y: { min: 0, max: 199 }, // Y座標は0以上199以下
168
+
169
+ z: { min: 100, max: 399 } // Z座標は100以上399以下
170
+
171
+ };
172
+
173
+ }
174
+
175
+
176
+
177
+ get x() {
178
+
179
+ const conf = this.constructor.config().x;
180
+
181
+ return Math.min(conf.max, Math.max(conf.min, this._x));
182
+
183
+ }
184
+
185
+ set x(value) { this._x = value; }
186
+
187
+
188
+
189
+ get y() {
190
+
191
+ const conf = this.constructor.config().y;
192
+
193
+ return Math.min(conf.max, Math.max(conf.min, this._y));
194
+
195
+ }
196
+
197
+ set y(value) { this._y = value; }
198
+
199
+
200
+
201
+ get z() {
202
+
203
+ const conf = this.constructor.config().z;
204
+
205
+ return Math.min(conf.max, Math.max(conf.min, this._z));
206
+
207
+ }
208
+
209
+ set z(value) { this._z = value; }
210
+
211
+
212
+
213
+ }
214
+
215
+
216
+
217
+ const p1 = new Point(-1, 230, 50);
218
+
219
+ console.log(`${p1}`); // => (x: -1, y: 230, z: 50)
220
+
221
+
222
+
223
+ p1.x = 1000;
224
+
225
+ console.log(p1.x); // => 1000
226
+
227
+
228
+
229
+ const p2 = new RestrictedPoint(-1, 230, 50);
230
+
231
+ console.log(`${p2}`); // => (x: 0, y: 199, z: 100)
232
+
233
+
234
+
235
+ p2.x = 1000;
236
+
237
+ console.log(p2.x); // => 99
238
+
239
+
240
+
241
+ ```
242
+
243
+
244
+
245
+ 以下に上記のコードを上げました。
246
+
247
+
248
+
249
+ [https://jsfiddle.net/cs86vtj3/65/](https://jsfiddle.net/cs86vtj3/65/)
250
+
251
+
252
+
253
+ 上記のコードの最後の2行に書いてあるように、`p2.x = 1000` と代入しても、 `p2.x` は X座標の上限値の`99`を返します。

5

テキスト修正

2018/08/10 01:38

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- 蛇足ですが、上記のように`Math.min`と`Math.max`を使った例として、3次元空間の点 `Point` を継承して、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成してみました。
19
+ 蛇足ですが、上記のように`Math.min`と`Math.max`を使った例として、あらかじめ設定された最小値と最大値の範囲に収まるように各座標が調整される、3次元空間の点`RestrictedPoint`を作成してみました。
20
20
 
21
21
 
22
22
 

4

テキスト修正

2018/08/09 23:24

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -54,11 +54,9 @@
54
54
 
55
55
  for ( const [axis, value] of Object.entries(this)) {
56
56
 
57
- const maxValue = RestrictedPoint.config[axis].max;
57
+ const config = this.constructor.config[axis];
58
58
 
59
- const minValue = RestrictedPoint.config[axis].min;
60
-
61
- this[axis] = Math.min(maxValue, Math.max(minValue, value));
59
+ this[axis] = Math.min(config.max, Math.max(config.min, value));
62
60
 
63
61
  }
64
62
 
@@ -98,4 +96,4 @@
98
96
 
99
97
  以下、上記を試行するサンプルです。
100
98
 
101
- [https://jsfiddle.net/jun68ykt/cs86vtj3/11/](https://jsfiddle.net/jun68ykt/cs86vtj3/11/)
99
+ [https://jsfiddle.net/jun68ykt/cs86vtj3/15/](https://jsfiddle.net/jun68ykt/cs86vtj3/15/)

3

テキスト修正

2018/08/09 23:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,13 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- ---
20
-
21
- 補足
22
-
23
-
24
-
25
- 蛇足ですが、上記を使って、3次元座標の点 `Point` を継承して、各座標の値と最値の範囲に収まるように調整される `RestrictedPoint` を作成してみました。
19
+ 蛇足ですが、上記のように`Math.min`と`Math.max`を使った例として、3次元空間の点 `Point` を継承して、あらかじめ設定された値と最値の範囲に収まるように各座標が調整される`RestrictedPoint`を作成してみました。
26
20
 
27
21
 
28
22
 

2

テキスト修正

2018/08/09 23:13

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -84,6 +84,20 @@
84
84
 
85
85
  };
86
86
 
87
+
88
+
89
+ const p1 = new Point(-1, 230, 50);
90
+
91
+ console.log(p1); // => Object {x=-1, y=230, z=50}
92
+
93
+
94
+
95
+ const p2 = new RestrictedPoint(-1, 230, 50);
96
+
97
+ console.log(p2); // => Object {x=0, y=199, z=100}
98
+
99
+
100
+
87
101
  ```
88
102
 
89
103
 

1

テキスト修正

2018/08/09 20:30

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -13,3 +13,81 @@
13
13
 
14
14
 
15
15
  ```
16
+
17
+
18
+
19
+ ---
20
+
21
+ 補足
22
+
23
+
24
+
25
+ 蛇足ですが、上記を使って、3次元座標の点 `Point` を継承して、各座標の最大値と最小値の範囲に収まるように調整される `RestrictedPoint` を作成してみました。
26
+
27
+
28
+
29
+ ```javascript
30
+
31
+ class Point {
32
+
33
+ constructor(x, y, z) {
34
+
35
+ this.x = x;
36
+
37
+ this.y = y;
38
+
39
+ this.z = z;
40
+
41
+ }
42
+
43
+ }
44
+
45
+
46
+
47
+ class RestrictedPoint extends Point {
48
+
49
+ constructor(x, y, z) {
50
+
51
+ super(x, y, z);
52
+
53
+ this.adjust();
54
+
55
+ }
56
+
57
+
58
+
59
+ adjust() {
60
+
61
+ for ( const [axis, value] of Object.entries(this)) {
62
+
63
+ const maxValue = RestrictedPoint.config[axis].max;
64
+
65
+ const minValue = RestrictedPoint.config[axis].min;
66
+
67
+ this[axis] = Math.min(maxValue, Math.max(minValue, value));
68
+
69
+ }
70
+
71
+ }
72
+
73
+ }
74
+
75
+
76
+
77
+ RestrictedPoint.config = {
78
+
79
+ x: { min: 0, max: 99 }, // X座標は0以上99以下
80
+
81
+ y: { min: 0, max: 199 }, // Y座標は0以上199以下
82
+
83
+ z: { min: 100, max: 399 } // Z座標は100以上399以下
84
+
85
+ };
86
+
87
+ ```
88
+
89
+
90
+
91
+ 以下、上記を試行するサンプルです。
92
+
93
+ [https://jsfiddle.net/jun68ykt/cs86vtj3/11/](https://jsfiddle.net/jun68ykt/cs86vtj3/11/)