kintone JavaScript APIでkintoneのレコード配列を操作するとき、大体下記のような感じになると思います。
for (var i = 0; i < records.length; i++) {
records[i]['フィールドコード']['value'] = 123;
}
これが最もベーシックだと思いますが、いくつか問題点があります。
-
i
の宣言が面倒 - データへアクセスするための記述量が長い(
records[i]['フィールドコード']['value']
) - 不等式を間違えたりして無限ループしてしまうなどのバグを起こしやすい
for
以外にも配列を扱う機能がJavaScriptには実装されているので、
状況に応じて、forEach
, filter
, map
などを使い分けていく方がスマートです。
実際にユースケースを見ながら使い方を見てみます。
(当記事はまだこれらの関数を使いこなせていない、使ったことがない方向けの内容です)
下記ページで実際に試すことのできる環境を用意しました。
結果はコンソールを開いて確認してください。
サンプル
顧客管理アプリのレコードを想定します。下記フィールドがあります。
フィールドコード | フィールドタイプ | 備考 |
---|---|---|
会社名 | 文字列一行 | 顧客の名前が格納される |
単価 | 数値 | 販売した製品の単価が格納される |
ユーザー数 | 数値 | 製品を購入したユーザー数を格納される |
小計 | 数値 | 購入額合計を格納するフィールド |
たとえば、上記のようなデータが有った場合、下記のような操作が必要になることがあります。
これを例にfor
と比較しながら見ていきます。
- 会社名一覧の取得
- 小計が10,000円以上のレコードのみを求める
- 小計を求める(消費税込)
- 全ての小計の合計
forEach
単純にすべてのレコードのデータを参照したい場合はforEach
を使うのが適しています。
Array.prototype.forEach()
例)会社名一覧の取得
-
for
で記述した場合
for (var i = 0; i < records.length; i++) {
console.log(records[i]['会社名']['value']); // 結果表示
}
forEach
で記述した場合
records.forEach(function(record){
console.log(record['会社名']['value']); // 結果表示
});
わざわざ、何行目かを意識せずとも、record
変数にrecords
のデータが1つずつ入って繰り返し処理を行ってくれますので見通しもよく便利です。
今までfor
でやっていることは、大抵このように実装できるはずですので、まずforEach
で実装できないか考えてみましょう。
ちなみに今何行目か、index変数にアクセスすることもできます。
- index変数にアクセス
records.forEach(function(record, i){
console.log(i + '行目の製品名: ' + record['製品名']['value']);
});
filter
filter
を使えば条件に一致した配列を取得できます。
例えば、売上n円以上のデータだけほしい、ということを簡単にかけます。
Array.prototype.filter()
例)小計が10,000円以上のレコードのみを求める
-
for
で記述した場合
var results = [];
for (var i = 0; i < records.length; i++) {
if (records[i]['小計']['value'] > 10000) {
results.push(records[i]);
}
}
console.log(results); // 結果表示
filter
で記述した場合
var results = records.filter(function(record){
return (record['小計']['value'] > 10000);
});
console.log(results); // 結果表示
if文を使わずとも任意のデータが取得できるので見た目もすっきりします。
実際には、この程度の条件であればkintone APIを呼ぶときに指定すればいいですが、もうちょっと複雑な条件を指定したいときには重宝します。
map
map
を使えば、配列全てに処理を行うことができます。(新しい配列が返却されます)
Array.prototype.map()
例)小計を求める(消費税込)
-
for
で記述した場合
var results = [];
for(var i = 0; i < records.length; i++) {
results.push(records[i]['小計']['value'] = records[i]['単価']['value'] * records[i]['ユーザー数']['value'] * 1.08);
}
map
で記述した場合
var results = records.map(function(record){
record['小計']['value'] = record['単価']['value'] * record['ユーザー数']['value'] * 1.08;
return record;
});
console.log(results); // 結果出力
これもタイプ数は大分減らせることが出来ました。
records[i]...
から始まらない分、短くてすみますし、バグを引き起こす可能性を低くすることができます。
実際には、小計を出す程度だと自動計算フォームを使えばいいですが、それではできない複雑な計算をする場合に使えます。
reduce
reduce
を使うとrecords配列の全ての合計値などを求めることができます。
reduceは上記に挙げたものと比べると少しむずかしく見えるかもしれませんが、慣れてしまえば簡単にデータの合計値などを求めることができます。
reduce
は左から右に配列を処理しますが、逆のreduceRight
もあります。
Array.prototype.reduce()
例)全ての小計の合計を求める
-
for
で記述した場合
var results = 0;
for(var i = 0; i < records.length; i++) {
results += records[i]['小計']['value'];
}
console.log(results); // 結果出力
reduce
で記述した場合
var results = records.reduce(function(prev, record){
return prev + record['小計']['value'];
}, 0);
console.log(results); // 結果出力
タイプ数は殆ど変わりませんので違いがわかりにくいですが、やはりindex変数i
を使わない分バグの確率は減ります。
forEach
でも実装はできますが、こちらはresults
の初期化も不要ですし、reduce
内で処理が完結するのでまとまりがあります。
例のように合計値を求めたり、records配列をloopしてデータを計算したいときは積極的につかっていきたい関数です。
まとめ
いかがでしょうか、for
しか使ったことがない場合は是非使ってみて下さい。最初は少しむずかしいかもしれませんが、慣れてしまえばfor
には戻れません。
単純にfor
を使うよりもバグを起こす可能性を減らせるだけでなく、見通しもいいので可読性もあがります。
これらの関数は比較的最近実装されたもので、Internet Explorer 9以上にしか実装されていません。しかし、kintoneも同様にIE9以上しかサポートしていないので、問題はないと思います。積極的に利用しましょう。
詳しい使い方や詳細については是非調べてみてください。上記以外にも有用な関数がたくさんあります。
注意点
-
for...in
ループを使っている方もいるかもしれませんが、推奨しません。理由はこちらです。 - 見やすさを優先してサンプルコードでは省いていますが、きちんと
Number()
などを使ってIntegerにparseしたほうがいいです。