「J らしい」機能の一つ、配列の計算です。
配列とは
J の配列は、多くのスクリプト言語とは異なり、固定長です。また、ジャグ配列ではないので、二次元配列のそれぞれの列の長さも揃っている必要があります (三次元以上の配列でも同様)。
さらに、全ての要素の型が同じでなければなりません。
ベクター
J では一次元配列をリスト (list) と呼び、その中でも数値のリストを特にベクター (vector) と言います。
ベクターは非常に簡単に書けます。
1 2 3
1 2 3
1.2 _3 _ 5e_8
1.2 _3 _ 5e_8
数値を空白で区切って並べるだけです。
ただ、簡単とは言え何度も手で入力するのは面倒なので、変数に代入しておきましょう。
a=: 8 7 2 6 3 1 3 NB. a に代入
a NB. a の値を確認
8 7 2 6 3 1 3
代入の記号は =:
です。:
(コロン) の位置に注意しましょう。
基本的な操作
配列の要素数を得るには、#
(monad) を使います。また、{
(dyad) 1 で要素の値を所得できます。
a
8 7 2 6 3 1 3
#a
7
0 { a
8
3 { a
6
7 { a
|index error
| 7 {a
インデックスは 0-オリジン (最初の要素が 0) です。範囲の外を指定すると index error が発生します。
ベクターの計算
ここからが本題です。
例えば、配列の各要素について計算したいとき、多くの言語では
- for / for each 文
- map 関数
の いずれかに相当するコードを書くでしょう。
J では、どちらも使いません。
a + 3 NB. ベクター + 数値
11 10 5 9 6 4 6
2 * a NB. 数値 * ベクター
16 14 4 12 6 2 6
-a NB. - ベクター
_8 _7 _2 _6 _3 _1 _3
普通の数値の計算と同じ書き方で配列も計算できます。J では数値が必要な場面でベクターが使われると、それぞれの要素に同じ verb が適用されます。
これにより反復処理を簡潔に書けるのが、J の強みの一つです。
ベクター同士の計算
前の例では、数値とベクターの計算をしました。ベクター同士の計算も試してみましょう。
1 2 3 + 4 5 6
5 7 9
1 2 3 4 * 1 0 2 _1
1 0 6 _4
同じように、要素ごとに計算されていることが分かりますね。
要素は一対一で対応している必要があります。要素数が違うと length error になります。
1 2 3 + 4 5
|length error
| 1 2 3 +4 5
リストの探索
J では単純な繰り返し以外に、要素の探索も簡単に書けます。
a
8 7 2 6 3 1 3
a i. 3 NB. 最初の 3 のインデックス
4
a i: 3 NB. 最後の 3 のインデックス
6
i.
(dyad) は先頭から、i:
(dyad) は末尾から探索して、はじめに見つかった所のインデックスを返します。
見つからなかった場合は、リストの長さが返ります。
#a
7
a i. 100
7
a i: 100
7
リストに値が含まれるかどうかだけ知りたい場合は、e.
(dyad) を使います 2。
NB. J では true は 1, false は 0
3 e. a
1
100 e. a
0
連番
i.
(monad) を使うと、0 から始まる整数のリストを作れます。よく使うので、覚えておいてください。
i.10
0 1 2 3 4 5 6 7 8 9
1 + i.10
1 2 3 4 5 6 7 8 9 10
要素の合計
さあ、あと一息です。
ベクターの要素を全て足し合わせる、という処理まで短く書けてしまうのが J です。
a
8 7 2 6 3 1 3
+/a
30
/
という新しい記号が出てきました。/
は、リストの要素と要素の間に verb (ここでは +
) を入れて、計算を行います。例えば、以下の 2 つの式は同じ計算をしています。
+/1 2 3 4 5
15
1 + 2 + 3 + 4 + 5
15
-/
も試してみましょう。
-/1 2 3 4 5
3
なぜ _13
にならないの?と思った方は、「右から」のルールを思い出してください 3。
1 - 2 - 3 - 4 - 5
3
(((1 - 2) - 3) - 4) - 5
_13
ところで、+/
の記号の順序について不思議に思った人がいるかもしれません。
ここまでは verb のみ紹介してきましたが、実は /
は verb ではなく adverb (副詞) に分類されます。大きな違いは、adverb は verb を引数 (被演算子) にできることです 4。
例えば、+/
の +
は adverb /
の引数になっています。
*adverb については、今は理解する必要はありません。*そういうものがある、ということだけ知っておいてください。
[ 前 : 数値と計算 ] [ 目次 ] [ 次 : 文字と文字列 ]