これを行う標準的な方法は次のとおりです。
行 (セル) 指向の構造を列指向の構造に変換する
各列に正しい動詞を適用する (1 回だけ)
手順 (1) は簡単です。ステップ (2) も簡単ですが、それほど明白ではありません。役立つちょっとしたトリックがあります。
秘訣は、多くのプリミティブ演算子が動名詞を左引数として受け入れ、動名詞を巡回して各動詞を順番に適用する関数を生成することを知っていることです。IMO、このカテゴリで最も便利な演算子は です;.
。これを使用した実装例を次に示します。
ステップ (0)、入力:
matrix =: ('abc';'defgh';23),:('foo';'bar';45)
columnTypes =: 'string';'string';'num'
DoString =: toupper
DoNum =: 0&j.
matrix
+---+-----+--+
|abc|defgh|23|
+---+-----+--+
|foo|bar |45|
+---+-----+--+
ステップ (1)、データの整理:
columnify =: <@:>"1@:|: :. rowify =: <"_1&>
columnify matrix
+---+-----+-----+
|abc|defgh|23 45|
|foo|bar | |
+---+-----+-----+
columnify には、データを再「rowify」する逆関数が用意されていることに注意してください。ただし、これを行うべきではありません。以下を参照してください。
ステップ (2) の動詞循環機能を使用して、正しい動詞を各列に (正確に 1 回) 適用します;.
。
homogenize =: ({. foo&.>@:{.`'') [^:('foo'-:])L:0~ ]
chain =: DoString`DoNum`] homogenize@{~ ('string';'num')&i.
不明な列タイプのデフォルトの変換は恒等関数であることに注意してください]
。
動詞homogenize
は、各列プロセッサの入力と出力を正規化します (つまり、ユーザーが変換の動的な「コア」のみを提供する必要があるように、前処理と後処理を抽象化します)。この動詞は、入力として列タイプのリストを取り、 (または同様の演算子)chain
の左側の引数を使用するのに適した動名詞を導出します。;.
したがって:
1 (chain columnTypes);.1 columnify matrix
+---+-----+---------+
|ABC|DEFGH|0j23 0j45|
|FOO|BAR | |
+---+-----+---------+
または、ボックス化されたセルの NxM テーブルが本当に必要な場合は、列化の「下」にカットを適用します。
1 (chain columnTypes);.1&.columnify matrix
+-----+-----+
|ABC |FOO |
+-----+-----+
|DEFGH|BAR |
+-----+-----+
|0j23 |0j45 |
+-----+-----+
ただし、J コンテキストでは、パフォーマンスと表記上の理由から、テーブルを同種の列のリストとして保持する方がはるかに適切であることに注意してください。
J は、配列を「まとめて」処理する場合に最適に機能します。経験則として、各アプリケーションでプリミティブまたはユーザー定義の名前にできるだけ多くのデータを表示させる必要があります。これが、この「列化」アプローチの主な利点です。データを同種の列のリストとして保存すると、後で操作するのが速くなり、簡単になります。
ただし、ユースケースで、ボックス化されたセルの NxM テーブルとしてデータを保持することが本当に必要な場合は、データを列の標準形式に変換したり、列の標準形式から変換したりするのは、費用がかかります。その場合、元のソリューションに固執する必要があります。
1 chain\"1 matrix
;.
これは(あなたが尋ねたため)実際にはアプローチと同じ前提で機能します。特に、\
動名詞引数を受け入れ、各動詞を連続して適用する (つまり、データの新しいウィンドウごとに周期的に適用する) 原始演算子の 1 つです。
実際に1 chain\"1 matrix
は、行列を行 ( "1
) に分割し、行ごとに 1 幅の移動ウィンドウ ( 1 f\ matrix
) を作成し、これらの 1 幅のウィンドウのそれぞれに動詞を周期的に適用しchain
ます (つまりf
、1 ごとに変化します)。 -行列の各行のデータ ウィンドウ全体)。
行の移動する 1-window (rank-1 ベクトル) は行のアトムであり、順序どおりであり、の動詞はchain
同じ順序で与えられるため、実際には、これらの動詞をの列に適用しています。マトリックス、1つ。原子。で。を。時間。
要するに: 1 chain\"1 matrix
は に似ていますがfoo"0 matrix
、foo はアトムごとに変更されます。また、一般的に回避する必要があるのと同じ理由で、これを回避する必要がありfoo"0 matrix
ます。小さなランクで関数を適用すると、J の粒度に反して動作し、パフォーマンスが低下するためです。
一般に、可能な限り高いランクで適用関数を使用することをお勧めします。この場合、matrix
列の正規形に変換 (および維持) する必要があります。
言い換えれば、ここで;.
は"1
そのまま\
です"0
。columnify
/の全体がhomogenize
( と比較して) 長すぎたりかさばったり1 chain\"1 matrix
する場合は、[1] で提供されているスクリプトをインポートできます。これは、これらの定義を拡張機能付きの再利用可能なユーティリティとしてパッケージ化したものです。例と手順については、ページを参照してください。
[1] 関連ユーティリティ スクリプト:
http://www.jsoftware.com/jwiki/DanBron/Snippets/DOOG