LoginSignup
262
158

More than 3 years have passed since last update.

JavaScript で配列の最後の要素を取得するもう一つの方法

Last updated at Posted at 2018-04-03

array[array.length - 1]array.pop() にはいくつかのデメリットがあり、使いづらいことがありますが、もう一つ良さそうな方法がありました。

  • array[array.length - 1]
    • メリット
      • (おそらく) 実行時間が一番短い (未検証)
    • デメリット
      • したいことの割に記述が長く、複雑なコード上では可読性が下がる
      • array という識別子を 2 重に記述することで、バグの原因になる可能性がある
      • 構文の都合上、何らかの計算結果で得た配列に対して用いるとき、一旦変数に代入しなければならない (メソッドチェーンで記述することができない)
  • array.pop()
    • メリット
      • コードを簡潔に記述することができ、ひとがコードを見て意味を理解しやすい
      • メソッドチェーンで記述することができる
    • デメリット
      • 元の配列が破壊される (それを目的とする場合はデメリットでない)

1. 結論: array.slice(-1)[0]

const array = [1, 2, 3, 4, 5];

const last = array.slice(-1)[0]; // ★これ

console.log({array, last}); // array: [1, 2, 3, 4, 5], last: 5

splice() ではなく slice() です。

slice() は配列の一部を新しい配列として取り出すことができるメソッドで、第一引数をマイナスにすると後ろからその要素数だけ取得します。
返り値の型は配列なので、[0] でスカラー値にしています。

  • array.slice(-1)[0]
    • メリット
      • コードを簡潔に記述することができ、ひとがコードを見てそこそこ意味を理解しやすい
      • メソッドチェーンで記述することができる
    • デメリット
      • (特になし)
      • しいて言えば、おそらく array[array.length - 1] より実行速度が遅い (未検証)

2. 配列いろいろ

念のため、空配列などの場合にどう動作するか確認しました。

// 普通の配列
const array1 = [1, 2, 3, 4, 5];
array1[array1.length - 1]; // 5
array1.slice(-1)[0]; // 5
array1.pop(); // 5

// 文字列
const array2 = '12345';
array2[array2.length - 1]; // '5'
array2.slice(-1)[0]; // '5'
array2.pop(); // (TypeError)

// 空配列
const array3 = [];
array3[array3.length - 1]; // undefined
array3.slice(-1)[0]; // undefined
array3.pop(); // undefined

// null, undefined
const array4 = null;
array4[array4.length - 1]; // (TypeError)
array4.slice(-1)[0]; // (TypeError)
array4.pop(); // (TypeError)

値を取得したいときに array[array.length - 1] が使える場面なら array.slice(-1)[0] を使って大丈夫そうです。

3. 他の解決策

3.1. ユーティリティ関数を作る

他の手段としては、ユーティリティ関数として機能を分離する方法が一番スマートだと思います。

const last = array => array[array.length - 1];

(実用的には別クラスの静的メソッドにした方がいいかもしれません。)

3.2. Array の継承クラスで last() メソッドを追加する

Array の継承クラスを作ることで last() メソッドを作ることができますが、最後の要素を取得するためだけにコード中の Array を全て変換しないといけなくなるります。

last() 以外にも機能を持つ別クラスを作る場合には有用だと思いますが、last() を追加するためだけに継承クラスを作るのはやりたいことの割にコードの可読性が下がり、あまり良くないかと思います。

3.3. 配列をメンバ変数に持つ別クラスを作る (状況次第)

配列をメンバ変数に持つ別クラスを作ると、配列の値やメソッドに直接アクセスできなくなりますが、それを目的とする場合は有効だと思います。

(最後の要素のみ取得できるということになり、このような状況になる可能性は少ない気がします。)

3.4. (非推奨) prototype に直接追加する

コメントを頂いた通り、Array に直接 last() メソッドを追加するのが一番分かりやすいですが、prototype にメソッドを直接追加することは混乱を招くと思いますので、使わない方が良いかと思います。

コメント「sliceはパッと理解してもらえないので、lastを作っちゃうのも手かと・・・

262
158
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
262
158