WEBVTT

1
00:00:00.000 --> 00:00:01.001
こんにちは。

2
00:00:01.001 --> 00:00:05.507
今回はジャバスクリプトのコピーウィズインを紹介します。

3
00:00:05.507 --> 00:00:11.514
これは、配列の一部分を、同じ配列の中の別の位置へコピーするメソッドです。

4
00:00:11.514 --> 00:00:17.522
コピー先にあった要素は上書きされますが、配列の長さは決して変わりません。

5
00:00:17.522 --> 00:00:24.030
新しい配列を作るのではなく、今ある配列をその場で書き換える点が大きな特徴です。

6
00:00:24.030 --> 00:00:29.120
たとえば、直近の計測値を四つだけ保ちたいとき、古い値をずらして空いた場所に新しい値を入れれば、

7
00:00:29.120 --> 00:00:34.209
同じ配列を使い続けられます。

8
00:00:34.209 --> 00:00:38.715
この動画では、基本の書き方から、範囲が重なる場合の動き、元の配列が変わってしまう注意点まで、

9
00:00:38.715 --> 00:00:43.221
順に解説します。

10
00:00:43.221 --> 00:00:49.228
初めて触れる方でも、実行結果を先に予測できるようになることを目指します。

11
00:00:49.228 --> 00:00:50.511
まず動作環境です。

12
00:00:50.511 --> 00:00:56.000
コピーウィズインは、二千十五年ごろから主要なブラウザーで広く使えるようになった機能で、

13
00:00:56.000 --> 00:01:01.488
現在のクローム、エッジ、ファイアフォックス、サファリで利用できます。

14
00:01:01.488 --> 00:01:08.902
ブラウザーで試すときは、空のタブを開き、開発者ツールのコンソールにコードを貼り付けるだけで実行できます。

15
00:01:08.902 --> 00:01:12.608
ドム操作は使わないので、手軽に結果を確かめられます。

16
00:01:12.608 --> 00:01:19.594
一方、ノード・ジェイエスでは、コードをファイルに保存し、ターミナルからノードコマンドで実行します。

17
00:01:19.594 --> 00:01:22.588
追加のライブラリーや特別な設定は不要です。

18
00:01:22.588 --> 00:01:29.288
古いブラウザーや組み込みの表示部品を対象にする場合は、事前に使えるかどうかを確認してください。

19
00:01:29.288 --> 00:01:31.412
基本の書き方を見ましょう。

20
00:01:31.412 --> 00:01:37.785
配列のあとにドット、コピーウィズインと書き、かっこの中に三つの引数を渡します。

21
00:01:37.785 --> 00:01:41.543
一つ目のターゲットは、コピー先の開始位置です。

22
00:01:41.543 --> 00:01:46.118
二つ目のスタートは、コピー元の開始位置、三つ目のエンドはコピー元の終了位置で、

23
00:01:46.118 --> 00:01:50.693
その位置の要素自体は含まれません。

24
00:01:50.693 --> 00:01:55.269
エンドを省略すると、配列の末尾までがコピー元になります。

25
00:01:55.269 --> 00:01:57.883
添字は先頭をゼロとして数えます。

26
00:01:57.883 --> 00:02:05.073
そして戻り値は、コピーした要素の数でも、新しい配列でもなく、変更された配列そのものです。

27
00:02:05.073 --> 00:02:11.772
この三つの位置関係を図で思い浮かべられるようになると、結果を予測しやすくなります。

28
00:02:11.772 --> 00:02:14.617
具体例で動きを確かめましょう。

29
00:02:14.617 --> 00:02:21.824
要素が一、二、三、四、五の配列で、コピーウィズイン、ゼロ、三と呼び出します。

30
00:02:21.824 --> 00:02:29.601
これは、添字三から末尾までの、四と五を、添字ゼロの位置へコピーするという意味です。

31
00:02:29.601 --> 00:02:33.015
結果は四、五、三、四、五となります。

32
00:02:33.015 --> 00:02:39.084
ポイントは、コピー元だった場所の値が消えるわけではないことです。

33
00:02:39.084 --> 00:02:46.860
コピー先にならなかった真ん中の三はそのまま残り、末尾の四と五も元の場所に残ります。

34
00:02:46.860 --> 00:02:52.930
あくまで上書きコピーなので、移動とは違う動きだと覚えてください。

35
00:02:52.930 --> 00:02:56.533
配列の長さは実行前と同じ五のままです。

36
00:02:56.533 --> 00:03:04.120
まずはこの基本パターンを、手元のコンソールで一度打ち込んで確かめてみてください。

37
00:03:04.120 --> 00:03:06.045
引数には負の数も使えます。

38
00:03:06.045 --> 00:03:10.043
負の添字は、配列の末尾から数えた位置として扱われます。

39
00:03:10.043 --> 00:03:14.782
たとえば長さ五の配列でマイナス二は、添字三と同じ場所を指します。

40
00:03:14.782 --> 00:03:20.261
画面の例では、末尾から二つ目の位置へ、先頭の二つの要素をコピーしています。

41
00:03:20.261 --> 00:03:23.666
また、コピーはコピー先の末尾で打ち切られます。

42
00:03:23.666 --> 00:03:29.886
ターゲットに配列の長さ以上の位置を指定すると、何もコピーされず、配列は変わりません。

43
00:03:29.886 --> 00:03:34.328
エンドがスタート以下になる場合も、コピー対象は空になります。

44
00:03:34.328 --> 00:03:41.732
ただし通常のコードでは、まずゼロ以上の整数で範囲を指定する方が、読み手に意図が伝わりやすくなります。

45
00:03:41.732 --> 00:03:43.709
ここからは実践例です。

46
00:03:43.709 --> 00:03:47.123
直近四回の計測値を保つ関数を作ります。

47
00:03:47.123 --> 00:03:49.458
処理の中心は二行だけです。

48
00:03:49.458 --> 00:03:56.825
まずコピーウィズイン、ゼロ、一で、二番目以降の値を先頭へコピーして左へずらします。

49
00:03:56.825 --> 00:04:00.599
次に、末尾の枠へ新しい計測値を代入します。

50
00:04:00.599 --> 00:04:05.271
たとえば十八、二十、十九、二十一という配列に二十二を加えると、二十、十九、

51
00:04:05.271 --> 00:04:09.942
二十一、二十二に更新されます。

52
00:04:09.942 --> 00:04:18.747
関数の前半では、配列かどうか、要素数が四かどうか、新しい値が有限の数かどうかを先に検査しています。

53
00:04:18.747 --> 00:04:27.192
変更前にまとめて検証することで、エラーが起きたときに配列が中途半端に書き換わる事態を防げます。

54
00:04:27.192 --> 00:04:31.439
先ほどの例では、コピー元とコピー先の範囲が重なっています。

55
00:04:31.439 --> 00:04:35.393
コピー元は添字一から三、コピー先は添字ゼロから二です。

56
00:04:35.393 --> 00:04:40.372
途中で上書きが起きるのに、なぜコピー元の並びが壊れないのでしょうか。

57
00:04:40.372 --> 00:04:44.911
コピーウィズインは、重なりを考慮して正しくコピーするよう定められているため、

58
00:04:44.911 --> 00:04:49.451
結果は二十、十九、二十一と正しい順序で写ります。

59
00:04:49.451 --> 00:04:53.259
コピー直後の配列は、二十、十九、二十一、二十一です。

60
00:04:53.259 --> 00:04:57.213
末尾の二十一はコピー先にならなかったので残っています。

61
00:04:57.213 --> 00:05:01.899
だからこそ、そのあと末尾へ新しい値を代入する手順が欠かせません。

62
00:05:01.899 --> 00:05:06.292
この代入を忘れると、古い値が重複したままになってしまいます。

63
00:05:06.292 --> 00:05:08.998
よくある勘違いが、戻り値の扱いです。

64
00:05:08.998 --> 00:05:15.462
コピーウィズインの戻り値を別の変数に入れても、それは元の配列と同じ実体を指しています。

65
00:05:15.462 --> 00:05:19.973
片方を変更すれば、もう片方からも同じ変更が見えてしまいます。

66
00:05:19.973 --> 00:05:25.234
変更前の状態を残しておきたい場合は、操作の前に配列を複製してください。

67
00:05:25.234 --> 00:05:30.271
画面の例では、スプレッド構文で複製した側だけにコピーウィズインを適用しているので、

68
00:05:30.271 --> 00:05:35.307
元の配列は十、二十、三十、四十のまま保たれています。

69
00:05:35.307 --> 00:05:37.863
ただし、この複製は浅いコピーです。

70
00:05:37.863 --> 00:05:42.673
要素がオブジェクトの場合、そのオブジェクト自体は複製されません。

71
00:05:42.673 --> 00:05:45.680
次のセクションで、その点を詳しく見ます。

72
00:05:45.680 --> 00:05:48.598
要素がオブジェクトの場合の注意点です。

73
00:05:48.598 --> 00:05:55.048
スコアが一と二の、二つのオブジェクトを持つ配列で、先頭の要素を二番目へコピーします。

74
00:05:55.048 --> 00:06:01.959
このときコピーされるのは、オブジェクトの中身の複製ではなく、同じオブジェクトへの参照です。

75
00:06:01.959 --> 00:06:07.642
そのため、二番目のスコアを九に書き換えると、一番目のスコアも九に見えます。

76
00:06:07.642 --> 00:06:12.249
両方の添字が、まったく同じオブジェクトを指しているからです。

77
00:06:12.249 --> 00:06:19.006
独立した編集用データを作りたい場面では、コピーウィズインをそのまま使うことはできません。

78
00:06:19.006 --> 00:06:24.228
用途に応じて、オブジェクト自体を複製する処理を別に用意してください。

79
00:06:24.228 --> 00:06:26.920
失敗例と制約も押さえておきましょう。

80
00:06:26.920 --> 00:06:34.249
要素を書き換えられない配列に対してコピーウィズインを使うと、タイプエラーが発生する場合があります。

81
00:06:34.249 --> 00:06:40.531
また、特殊な読み書き処理を持つ配列では、コピーの途中で例外が起きる可能性もあります。

82
00:06:40.531 --> 00:06:45.467
その場合、すでに書き換わった部分が自動で元に戻る保証はありません。

83
00:06:45.467 --> 00:06:51.151
さらに、空きスロットのある疎な配列では、その空き自体もコピー先へ伝わります。

84
00:06:51.151 --> 00:06:56.984
安全に使うコツは、普段自分で作った、空きのない通常の配列を対象にすることです。

85
00:06:56.984 --> 00:07:01.322
この処理は同期的で、アウェイトやプロミスの待機は不要です。

86
00:07:01.322 --> 00:07:06.856
例外はその場で発生するので、必要に応じてトライ・キャッチで囲んでください。

87
00:07:06.856 --> 00:07:09.028
最後に活用場面とまとめです。

88
00:07:09.028 --> 00:07:14.225
コピーウィズインが向いているのは、直近の計測値、一定数の処理時間、固定幅の作業データなど、

89
00:07:14.225 --> 00:07:19.422
要素数を保ったまま範囲をずらしたい場面です。

90
00:07:19.422 --> 00:07:23.766
逆に、一覧の途中に要素を挿入したり削除したりしたい場合は、求める操作が違うので、

91
00:07:23.766 --> 00:07:28.110
別のメソッドを検討してください。

92
00:07:28.110 --> 00:07:36.798
導入するときは、更新処理を関数の形にまとめ、元の配列が変わることを呼び出し側にも分かるようにしておくと安全です。

93
00:07:36.798 --> 00:07:43.004
複数の場所で同じ配列を共有している場合は、上書きの影響範囲を先に確認しましょう。

94
00:07:43.004 --> 00:07:48.124
合言葉は、長さを変えずに、その場でずらすならコピーウィズインです。

95
00:07:48.124 --> 00:07:54.640
範囲の指定に慣れるまでは、小さな配列で結果を予測してから実行する練習がおすすめです。

96
00:07:54.640 --> 00:07:56.036
お疲れさまでした。
