January 16, 2006

@関数式:UniqueなListからある値だけを除外

テーマ:Hints & Tips

みなさん、NotesでProgrammingをしている時に、あるUniqueなListからある値だけを除外したいといったことがあるのではないでしょうか?


ここで考えるのは、@Replaceを使って値を""とかで置き換えてしまうことですが、""を使って@Replaceで値を置き換えても、""がListの中に残ってしまいますし、@Uniqueを行っても全ての""を消し去ることはできません。


また、@Replaceを行う際には、置き換えるFromListよりもToListの要素数が少ない場合、Null("")が残ってしまうという結果になります。


こんな時には、これらの動きから、""が残ってしまうことを逆に利用してしまうことを考えます。


例えば、以下のように書いて見ましょう。


List := "A": "B" : "C" : "D": "E":"F":"G":"H";
TempSourceList :="" : List ;
FromList := @Prompt([OKCANCELLISTMULT] ; "Please Select Elements you wish delete" ; "Please Select" ; "" ;List);
ToList := "";
TempList :=@Unique(@Replace(TempSourceList ; FromList; ToList));
ResultList := @Subset(TempList ; -(@Elements(TempList)-1));
@Prompt([OK] ; "Result" ; @Implode(ResultList ; ","))


最初のListが元のDataですが、最初にこのListの先頭に""を付け加えておきます。


つまり、この場合は、元のListの中に絶対に必要な値として""が無いということが前提となります。


その後、ここでは@PromptでListから削除したい値を入力させ、その値を@Replaceを使って""に置き換え、@Uniqueで複数ある""を除外しますが、Listの先頭に""を加えているので、最初の""だけが残ることになります(@Replaceで生成されてしまった""も除外されます)。


最後に@Subsetを使って、後ろからListの数-1だけを抜き出してやれば、希望した値だけを抜いたUnique Listができるというわけです。


あるいは、@Trimが""(Null)を除外してくれることを利用することもできます。


ただ、この場合は@Trimによって複数Spaceが一つになってしまいますので、Spaceの数に意味がある場合には使えません。


List := "A": "B" : "C" : "D": "E":"F":"G":"H";
FromList := @Prompt([OkCancelListMult] ; "Please Select Elements you wish delete" ; "Please Select" ; "" ;List);
ToList := "";
ResultList :=@Trim(@Replace(List ; FromList; ToList));
@Prompt([Ok] ; "Result" ; @Implode(ResultList ; ","))



しかし、これでは""がListに必要な値として入っている場合はうまく処理ができないといった問題があります。


これを回避するために、以下のようなCodeにすることも考えられます。


以下の場合は、""に決めてReplaceするといったことはせずに、除外したい値をListの前に足して、@Uniqueすることにより、元のListにあった値を除外し、後で、@Subsetで最初に付け足した値を抜いてしまうという手法です。


List := "A": "B" : "C" : "D": "E":"F":"G":"H";
FromList := @Prompt([OkCancelListMult] ; "Please Select Elements you wish delete" ; "Please Select" ; "" ;List);
TempSourceList :=FromList : List ;
TempList :=@Unique(TempSourceList);
ResultList := @Subset(TempList ; -(@Elements(TempList)-@Elements(FromList)));
@Prompt([Ok] ; "Result" ; @Implode(ResultList ; ","))



これらの式はR5でも動作させることができます。




しかし、これらの場合は、最初に書いたように、元のListがUniqueである必要があります。


その為に、Notes 6以降では@Nothingと@Transformが追加されているのです。


例えば、上記の式はNotes 6以降では以下のように書き換えることができます。


List := "A": "B" : "C" : "D": "E":"F":"G":"H";
FromList := @Prompt([OkCancelListMult] ; "Please Select Elements you wish delete" ; "Please Select" ; "" ;List);
ResultList :=@Transform(List;"x";@If(@IsMember(x;FromList);@Nothing;x));
@Prompt([Ok] ; "Result" ; @Implode(ResultList ; ","))


この場合は元のListは必ずしもUniqueである必要はありません。指定した抜き出したい値が元のListにあればその値を@Nothingでなくしてしまうことができるのです。


このように、新しい@関数式を使うと、従来複雑な処理を行っていた物がいとも簡単に実現できてしまうわけです。


いかがでしょうか?


ちょっとしたTipsですが、役に立つこともあるのではないでしょうか?

コメント

[コメントをする]

コメント投稿

[PR]気になるキーワード