Kinx ライブラリ - Array

# Array

## はじめに

**「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。言語はライブラリが命。ということでライブラリの使い方編。 

今回は Array です。

* 参考
    * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
        * 個別記事へのリンクは全てここに集約してあります。
    * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
        * Pull Request 等お待ちしております。 

## Array 特殊オブジェクト

Array オブジェクトに対して関数定義する例は以下の通り。例では単に map をラップしただけですが。

```javascript
Array.plus1 = function(ary) {
    return ary.map(&(e) => e + 1);
};
var val = [1,2,3,4,5].plus1();
System.println(val.toJsonString());
```

実行してみよう。

```
[2,3,4,5,6]
```

他の特殊オブジェクトと同様、レシーバーが第 1 引数に来ます。

## Array

### 組み込み特殊メソッド

~~破壊的なメソッドはない。あったほうが良ければ後で考える~~。`push`、`pop`、`unshift`、`shift` は破壊的なメソッドでした。

|              メソッド              |                                                                   意味                                                                    |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Array.length(ary)                  | 配列 ary の要素数を返す。                                                                                                                 |
| Array.keySet(obj)                  | オブジェクト obj のキー一覧を配列として返す。                                                                                             |
| Array.push(ary, e)                 | 配列 ary の最後の要素として e を追加する。                                                                                                |
| Array.pop(ary)                     | 配列 ary の最後の要素を返し、要素から削除する。                                                                                           |
| Array.unshift(ary, e)              | 配列 ary の最初の要素として e を追加する。                                                                                                |
| Array.shift(ary)                   | 配列 ary の最初の要素を返し、要素から削除する。後ろの要素は順次先頭方向に移動する。                                                       |
| Array.join(ary, sep)               | 配列 ary の要素を全てつなげた文字列として返す。要素と要素の間は sep でつなぐ。                                                            |
| Array.reverse(ary)                 | 配列 ary の要素を逆順にした新たな配列を返す。                                                                                             |
| Array.flatten(ary)                 | 配列 ary の要素をフラットにした形で新たな配列として返す。                                                                                 |
| Array.toString(ary)                | 配列 ary を文字列化して返す。デフォルトのセパレータは `", "`                                                                              |
| Array.toJsonString(ary, useIndent) | 配列 ary を JSON 文字列化して返す。useIndent を true とすると、インデントした形で整形する。                                               |
| Array.apply(ary, func)             | func(ary) を実行する。                                                                                                                    |
| Array.each(ary, callback)          | ary の各要素 e に対して callback(e, index) を実行する。                                                                                   |
| Array.map(ary, callback)           | ary の各要素 e に対して callback(e, index) の結果の集合となる新たな配列を返す。                                                           |
| Array.flatMap(ary, func)           | map した新たな配列をフラットにして返す。                                                                                                  |
| Array.filter(ary, callback)        | ary の各要素 e に対して callback(e, index) の結果が真となるもののみの集合として新たな配列を返す。                                         |
| Array.reject(ary, callback)        | ary の各要素 e に対して callback(e, index) の結果が偽となるもののみの集合として新たな配列を返す。                                         |
| Array.reduce(ary, callback, initr) | 前の要素までの結果を r （初期値は initr、指定されていなければ null）として、ary の各要素 e に対し callback(r, e) を行った最終結果を返す。 |
| Array.sort(ary, comp)              | 任意の ary の要素 e1, e2 に対する comp(e1, e2) の結果を利用して ary 全体をソートした新たな配列を返す。                                    |
| Array.clone(obj)                   | obj のディープ・コピーを作成する。                                                                                                        |
| Array.extend(obj, obj2)            | obj の内容を obj2 の内容で拡張する。同じキーがあれば上書きする。                                                                          |
| Array.println(ary)                 | ary の各要素 e に対して System.println(e) を適用する。                                                                                    |

Array の特殊メソッドはオブジェクトにも適用されることに注意。使い分ける場合は呼び出された後に区別する。

### 配列（Array）とオブジェクト（Object）の区別について

型チェック用のプロパティとして `isArray` と `isObject` が存在する。尚、`a.isArray == true` であれば `a.isObject == true` でもあるので、先に `isArray` でチェックする。

| プロパティ |                           真となる条件                            |
| ---------- | ----------------------------------------------------------------- |
| `isObject` | 配列、オブジェクト、クラス・インスタンス                          |
| `isArray`  | `e.isObject == true` である e のうち、配列要素が 1 つ以上あるもの |

### 特殊オペレーター

#### 後置 `[]` オペレーター

配列の要素にアクセスする。

```javascript
var e = ary[5];  // index は 0 はじまりなので 6 番目の要素
```

左辺値にもなり、配列要素を直接書き換えることができる。

```javascript
var ary = [1,2,3,4,5];
ary[2] = 0.5;
System.println(ary);  // => [1, 2, 0.5, 4, 5]
```

#### 二項 `+` オペレーター

配列同士をつなげる。右辺値が配列ではない場合、`SystemException("Unsupported Operator")` 例外が発生する。

```javascript
var ary = [1, 2, 3];
var r = ary + [2, 4];  // => [1, 2, 3, 2, 4]
```

#### 単項 `*` オペレーター

単項 `*` オペレーターを配列に適用した場合、配列を文字列に変換する。この時、

```javascript
var a = *[97, 98, 99];  // => "abc"
```

尚、補足として文字列に単項 `*` オペレーターを適用すると、配列に戻ってくる。

## おわりに

Array に対する特殊メソッドはたくさんあるのだが、細部をもうちょっと練るかもしれない。例えば、`Array.toString()` は連結する際に要素としてのオブジェクトが `toString()` メソッドを持っていたらそれを適用してから連結するとか。

> **追伸**
> この機能（`toString` をあらかじめ適用する機能）、はプレビュー 0.5.1 で入りました。`System.println()` 等で表示する際も、オブジェクトが `toString()` メソッドを持っていれば、それを適用してから表示します。これによって、オブジェクトの表示形式を自由に制御できるようになります。

では、また次回。