push は先頭 or 末尾

配列に要素を追加する時、push は要注意だ。可能なら別の方法で追加したほうが良いと思う。

Java の場合、push は、「先頭」に要素を追加する関数だが、JavaScriptの場合は「末尾」に要素を追加する。

先頭に要素を追加したい場合

Java の場合は、add(0, 追加したい要素) がわかりやすい。 JavaScript の場合は、unshift(追加したい要素) が一般的だろうか。 JavaScript の配列操作は単語の意味と結果が一致しないので混乱している人が多い。 unshift って、そもそも shift って何?って感じだ。 Javaのaddは、要素を追加するの add だから、何も指示がなければ、殆の人は末尾への追加をイメージするだろうし、 add(0, 要素) と書けば、0 番目に追加(つまり先頭へ追加する)とイメージしやすい。 あくまでも基本イメージは、add (追加)なので、先頭要素が入れ替わると考える人は変人だ。

末尾に要素を追加したい場合

Javaの場合は、ずばり、add(追加したい要素)で明快。 JavaScript の場合は shift かと思いきや、さにあらず。 array[array.length] = 追加したい要素 で追加する。やはり分かりづらい。 shift は何かというと、先頭要素を取り出す操作になる。

JavaScript の変態仕様

  • shift : 先頭要素を取り出す
  • unshift : 先頭に要素を追加する
  • pop : 末尾要素を取り出す
  • push : 末尾に要素を追加する

これは、私のそれぞれの単語からくるイメージとはかなり違って覚えづらい

Groovy の罠

うちの会社では、Groovy という言語を良く使うのだが、これは Javaに翻訳されて動作するスクリプト言語なのだが、 2017年頃までは、 push は、末尾に要素を追加していた。これが、2013年頃に報告された、「Javaと反対じゃん」というバグに対応したことによって、今は、先頭に要素を追加する関数になっている。真逆。そのため、古い Grooby で書かれたコードで、push が使われている場合、それはまともに動作しないことがある。配列の並び順を意識した処理の場合、完全に並び順が逆になるのだ。その配列に初期値が与えられている場合、更に意味不明になる。何らかの処理で取得した配列、初期値は、意図した順に並んでいるが、あとから push で追加したものだけが、先頭に追加されるので、めちゃくちゃになってしまう。

こういう問題があるので、 push を安易に使うのはやめましょう。と私は言いたい。言葉として曖昧なもの、動作が明確にイメージできない名称の関数は要注意だ。

カテゴリー: ZAKKI パーマリンク