Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
115
Help us understand the problem. What are the problem?
@kerupani129

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

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を作っちゃうのも手かと・・・

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
115
Help us understand the problem. What are the problem?