私はLodash(javascriptライブラリ)(https://lodash.com/docs/4.17.4#filter)のフィルタ関数をシミュレートする次のprocを書きました。サンプルセクションにある3.5の基本形式で呼び出すことができます。後者の3つの呼び出しオプションについては、-s(略記)を送るという要求を取り除きたいと思っています。そのためには、匿名のprocとlist/dict/stringを区別する必要があります。Tcl - list/dictと匿名プロキシの区別
string is
を見てみましたが、文字列がprocではありません。ここでの研究ではhttp://wiki.tcl.tk/10166info complete
をお勧めしますが、ほとんどの場合、パラメータの種類に関係なく、そのテストに合格します。
これを信頼できる方法を知っている人はいますか?私はそれを残したり、proc定義を変更することができますが、私はできるだけ真実にとどまるよう努めています。
例:
set users [list \
[dict create user barney age 36 active true] \
[dict create user fred age 40 active false] \
]
1. set result [_filter [list 1 2 3 4] {x {return true}}]
2. set result [_filter $users -s [dict create age 36 active true]]
3. set result [_filter $users -s [list age 36]]
4. set result [_filter $users -s "active"]
PROCコード:
proc _filter {collection predicate args} {
# They want to use shorthand syntax
if {$predicate=="-s"} {
# They passed a list/dict
if {[_dictIs {*}$args]} {
set predicate {x {
upvar args args
set truthy 1
dict for {k v} {*}$args {
if {[dict get $x $k]!=$v} {
set truthy false
break
}
}
return $truthy
}}
# They passed just an individual string
} else {
set predicate {x {
upvar args args;
if {[dict get $x $args]} {
return true;
}
return false;
}}
}
}
# Start the result list and the index (which may not be used)
set result {}
set i -1
# For each item in collection apply the iteratee.
# Dynamically pass the correct parameters.
set paramLen [llength [lindex $predicate 0]]
foreach item $collection {
set param [list $item]
if {$paramLen>=2} {lappend param [incr i];}
if {$paramLen>=3} {lappend param $collection;}
if {[apply $predicate {*}$param]} {
lappend result $item
}
}
return $result
}
ラムダ用語がこれを持っていると言う人は賢明な方法を持っていたのですが、リスト/ dict /ストリングはそうではありません。私が見る唯一の潜在的な違いは、lambda = 2または3です。もし3ならば、私はラムダを仮定することができます。しかし、もしlen = 2ならば、私が考えることができるのは、最初のコンポーネント(args)を見て、それが1より大きいかどうか、もしそうなら、ラムダまたはスペースを持つdictキーでしょうか。最終的に、私は同じ結論に達しましたが、誰かがもっと賢いかどうかを見たいと思っていました... –