forEach, map, filterなどをつかってkintoneのrecords配列をもっと上手に扱う


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`などを使い分けていく方がスマートです。
実際にユースケースを見ながら使い方を見てみます。
(当記事はまだこれらの関数を使いこなせていない、使ったことがない方向けの内容です)

下記ページで実際に試すことのできる環境を用意しました。
結果はコンソールを開いて確認してください。

https://jsfiddle.net/emgujhxj/2/

## サンプル
顧客管理アプリのレコードを想定します。下記フィールドがあります。


| フィールドコード | フィールドタイプ | 備考 |
|--------|--------|--------|
| 会社名  | 文字列一行 | 顧客の名前が格納される|
| 単価 | 数値 | 販売した製品の単価が格納される |
| ユーザー数 | 数値 | 製品を購入したユーザー数を格納される |
| 小計 | 数値 | 購入額合計を格納するフィールド |


たとえば、上記のようなデータが有った場合、下記のような操作が必要になることがあります。
これを例に`for`と比較しながら見ていきます。

- 会社名一覧の取得
- 小計が10,000円以上のレコードのみを求める
- 小計を求める(消費税込)
- 全ての小計の合計

## forEach
単純にすべてのレコードのデータを参照したい場合は`forEach`を使うのが適しています。  
[Array.prototype.forEach()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)

### 例）会社名一覧の取得

- `for`で記述した場合

```js
for (var i = 0; i < records.length; i++) {
  console.log(records[i]['会社名']['value']); // 結果表示
}
```

- **`forEach`で記述した場合**

```js
records.forEach(function(record){
  console.log(record['会社名']['value']);  // 結果表示
});
```

わざわざ、何行目かを意識せずとも、`record`変数に`records`のデータが1つずつ入って繰り返し処理を行ってくれますので見通しもよく便利です。
今まで`for`でやっていることは、大抵このように実装できるはずですので、まず`forEach`で実装できないか考えてみましょう。

ちなみに今何行目か、index変数にアクセスすることもできます。

- index変数にアクセス

```js
records.forEach(function(record, i){
  console.log(i + '行目の製品名: ' + record['製品名']['value']);
});
```

## filter
`filter`を使えば条件に一致した配列を取得できます。
例えば、売上n円以上のデータだけほしい、ということを簡単にかけます。  
[Array.prototype.filter()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

### 例）小計が10,000円以上のレコードのみを求める

- `for`で記述した場合

```js
var results = [];
for (var i = 0; i < records.length; i++) {
  if (records[i]['小計']['value'] > 10000) {
    results.push(records[i]);
  }
}
console.log(results); // 結果表示
```

- **`filter`で記述した場合**

```js
var results = records.filter(function(record){
  return (record['小計']['value'] > 10000);
});
console.log(results); // 結果表示
```

if文を使わずとも任意のデータが取得できるので見た目もすっきりします。
実際には、この程度の条件であればkintone APIを呼ぶときに指定すればいいですが、もうちょっと複雑な条件を指定したいときには重宝します。

## map
`map`を使えば、配列全てに処理を行うことができます。(新しい配列が返却されます)
[Array.prototype.map()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

### 例）小計を求める(消費税込)

- `for`で記述した場合

```js
var results = [];
for(var i = 0; i < records.length; i++) {
  results.push(records[i]['小計']['value'] = records[i]['単価']['value'] * records[i]['ユーザー数']['value'] * 1.08);
}
```

- **`map`で記述した場合**

```js
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()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)

### 例）全ての小計の合計を求める

- `for`で記述した場合

```js
var results = 0;
for(var i = 0; i < records.length; i++) {
  results += records[i]['小計']['value'];
}
console.log(results); // 結果出力
```

- **`reduce`で記述した場合**

```js
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`ループを使っている方もいるかもしれませんが、推奨しません。理由は[こちら](http://www.ituore.com/entry/javascript-for#for-inの注意点)です。
- 見やすさを優先してサンプルコードでは省いていますが、きちんと`Number()`などを使ってIntegerにparseしたほうがいいです。