JavaScriptで、配列の最大値を取得する方法について。
最初に答えを書いておくと、Math.max(...targetArray)
。
旧来はapplyを使うのが主流だった?
Math.max()
を使うと、数値の中から最大のものを取得できる。
Math.max(6, 8, 9, 7); // 9
しかしこれは、一つずつ数を渡す必要があり、配列を渡すことは出来ない。
配列でMath.max()
を使うにはどうすればいいのか。
apply
を使えば解決する。
const array = [3, 8, 7, 2, 5]; Math.max.apply(null, array); // 8
apply
の第二引数には配列を渡して使うが、この配列の要素が1つずつ引数として渡される。
そのため、配列を展開してそれを引数として渡す手段として、apply
が有用なのだ。
このテクニックは有名らしく、Math.max.apply(null, array);
の記法も、「イディオム」とすら言われている。
事実、「JavaScript 配列 最大値」などで調べると、大体これが出てくる。
スプレッド演算子を使う
だがES2015なら、もっとシンプルに書ける。
先程、「配列を展開してそれを引数として渡す手段」と書いたが、ES2015で使えるようになったスプレッド演算子は、まさにそういった使い方が出来る。
const array = [3, 8, 7, 2, 5]; Math.max(...array); // 8
スプレッド演算子そのものの説明はこちら。
オブジェクトの配列から、特定のプロパティの最大値を取得する
次のような、オブジェクトが要素として格納された配列があったとする。
const memberList = [ { name: 'Tom', age: 20 }, { name: 'Bob', age: 25 }, { name: 'Cate', age: 23 }, { name: 'John', age: 18 }, ];
この中から、age
の最大値を取得したい。このようなケースでも、先程の書き方で対応できる。
Math.max(...memberList.map(m => m.age)); // 25
map
でage
の配列を作り、それをスプレッド演算子で展開してMath.max()
に渡している。
プログラマとしての能力
得意気に書いてきたが、今回書いたものは、自分で考えたものでもなければ、自分で調べたものでもない。
職場のコードレビューで教えてもらったものである。
上記の、memberList
からage
の最大値を取得したい、というようなケースに遭遇した。
その際に自分が書いたのが、以下のようなコード。
Math.max()
すら使っていない。
const ages = []; let maxAge = 0; for (let i = 0; i < memberList.length; i++) { ages.push(memberList[i].age); } for (let i = 0; i < ages.length; i++) { if (ages[i] > maxAge) maxAge = ages[i]; } console.log(maxAge);
すぐに、最大値を取得するならMath.max()
を使ったほうが分かりやすい、という指摘を受けた。
恥ずかしながらMath.max()
を使ったことがなかったので、ネットで調べた。apply
を使ったテクニックも、その時に知った。
以下のように書き換えることで、多少は見通しがよくなった。
const ages = []; for (let i = 0; i < memberList.length; i++) { ages.push(memberList[i].age); } console.log(Math.max.apply(null, ages));
だがこれでも不十分だった。
map
とスプレッド演算子を使ったやり方を教えてもらい、それに書き換えた。
console.log(Math.max(...memberList.map(m => m.age)));
俺が9行もダラダラと書いてきたことを、たった1行で表現してしまっている。
可読性や保守性を犠牲にしてトリッキーなことをしている訳でもないのに。
いくらES2015の機能を知っていたとしても、使い方が分からなければ意味がない。
そのことを思い知らされた。
慣れもあるとは思う。場数を踏むことで、すぐに適切なコードが思い浮かぶようになる、というのはあるはず。
だがそれにしても、map
やスプレッド演算子を使えばいいなんて、ちょっと考えればすぐに分かりそうなものなのに。
知識がたくさんあるのは大事だし、いわゆるベストプラクティスを知っていることも大事。
でもそれだけじゃなく、使いこなす能力というか、解決すべき問題は何で、どのようにアプローチすべきで、そのためにどの道具を使えばいいのか、ということを考える能力が必要なんだろう。それこそが、プログラマの能力のような気がする。
思考力とか認識力のようなもの。
後は、やっぱり実務経験が大切というか、ネットで調べて得たものよりも遥かに妥当な内容がコードレビューで返ってきて、笑ってしまった。
いくらプログラミングはネットで独学しやすいとはいえ、優秀な人と一緒に働くほうが、はるかに成長効率がよい。