[Javascript] データベースから取り出したデータの中の複数カラム値を合計して3桁毎にカンマを付与した値を一発で取得する方法

とある仕事で使ったコードの備忘録。 JavascriptからAjaxを使って、サーバーからデータベースの情報をそのままselect文で取得した時って、連想配列(レコード)が結果分の個数配列に格納されている状態になっています。 この中の特定のカラム情報の値だけをコピーしたいという場合に、便利に1行でできるスニペを書いたので、その解説と合わせてよく使うコードとして備忘録しておきます。

取得したデータサンプル

とあるショップサイトの売上データをデータベースから取得したのが次のような感じです。(サンプルです) 取得した値を下記のように、datasに格納しておきます。 const datas = [ { "id" : "1", "name" : "apple", "profit" : 1500 }, { "id" : "2", "name" : "banana", "profit" : 2000 }, { "id" : "3", "name" : "orange", "profit" : 1200 } ] この中で、profitカラムの値を足し込みたいと思います。

profitだけの値を抜き出した配列を作る

datas.map(e => e.profit)

結果

> [1500, 2000, 1200]

配列の値を全て合計する

datas.map(e => e.profit).reduce((a,b)=>{return a+b})
> 4700

安定したプログラムへの思考

上記の段階で、合計値が取得できて終わりと考えたのであれば、恐らくバグを出すプログラムが出来上がってしまいます。 例えば、データベースで取得した結果のprofit値がなかった場合、null値が入っていた場合どうなるでしょう?

const datas = [ { "id" : "1", "name" : "apple", "profit" : 1500 }, { "id" : "2", "name" : "banana", "profit" : 2000 }, { "id" : "3", "name" : "orange", "profit" : 1200 }, { "id" : "4", "name" : "kiwi", "profit" : null } ]

この場合の結果は、NaNが返ってきます。 これを防止するために、あと、profitの値が、文字列で返ってきた場合も考慮して、次のようなコードに変更しました。 datas.map(e => e.profit).reduce((a,b)=>{return Number(a||0)+Number(b||0)})

解説

reduce内のaとbの変数をNumber(...)関数で、数値化して、a||0として、nullやundefinedやブランクの場合に0という値に変換するようにしました。

3桁カンマ処理

最後に、表示するときに、3桁ごとにカンマを付けた形に変換します。 datas.map(e => e.profit).reduce((a,b)=>{return Number(a||0)+Number(b||0)}).toLocaleString()
4,700