
に触発された数式で使用されている列を抽出する方法はありますか?そしてイアン@JMPコメント。
dt = New Table( "Get Columns in Formula",
Add Rows( 20 ),
New Column( "H", Numeric, "Continuous", Format( "Best", 12 ), Formula( Random Uniform() ) ),
New Column( "W", Numeric, "Continuous", Format( "Best", 12 ), Formula( Random Uniform() ) ),
New Column( "D", Numeric, "Continuous", Format( "Best", 12 ), Formula( Random Uniform() ) ),
New Column( "V", Numeric, "Continuous", Format( "Best", 12 ), Formula( (:W * :H * :D) / 10 ) )
);
formula = dt:V << getformula();
// function to find leaves in formula that are columns in the table
findColumns = Function( {frm, cols},
{h = Head( frm ), n = N Arg( frm ), i, result = {}}, // local variables
If( n == 0, // head node has no children, it is a leaf
If( Contains( cols, Name Expr( h ) ), // is the leaf in the list of columns?
Insert Into( result, Name Expr( h ) ); // yes -> add to result
)
,
For( i = 1, i <= n, i++, // not a leaf, get children's results
Insert Into( result, Recurse( Arg( frm, i ), cols ) )
)
);
result// return the result
);
answer = findColumns( Name Expr( formula ), dt << GetColumnNames );
Show( formula, answer );
式 = (:W * :H *
) / 10;
答え = {:W、:H、:D};
の列の検索10 ~ 22 行目で定義された関数は 2 つの引数を取ります。から、調べる式、そしてコル、抽出する有効な列名のリスト。の頭式の例は Divide(...) で、これには 2 つの子があります (答えはN 引数)。 if ステートメントは子があることを確認し、再帰各子を処理する関数。乗算子には 3 人の子供がいます。:W 子には子がなく、データ テーブルの列のリストには :W が含まれるため、:W は次のようになります。に挿入されたリストと返されたリスト。そのリストはリストに挿入されます。次に、乗算の子は 2 番目の値を送信します。引数再帰的に実行し、:H を追加します。結局10は(ディバイドの2番目の子)は recurse に送信されますが、列のリストにないため、回答には表示されません。
再帰には毎回ある程度の労力がかかります。しかし、それは単純に見えるプログラムを作成します。