Snažím se reprodukovat API funkce (napsané v R), která přijímá libovolný počet argumentů a zachází s ní stejným způsobem, jako by zpracovávala jediný argument, který je seznam různých datových sad.
Existuje idiom Mathematica, který umožňuje definovat funkci tak, aby:
f[ arg1, arg2, ..., argN ]
se choval stejné jako
f[ {arg1, arg2, ..., argN} ]
?
Komentáře
Odpověď
Jak popsal Andy Ross v komentáři, můžete vytvořit definici, která předzpracuje argumenty do kanonické podoby. Aby příklad ilustroval flexibilitu, obrátil svůj příklad:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
Pravda
Tato metoda je užitečná pro složitější předzpracování, ale v jednoduchých případech, jako je tato, je často snazší použít Alternatives
:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
Pravda
Uvědomte si, že když pomocí Alternatives
musíte ručně objednat vzory, protože jsou zkoušeny postupně. Vzor args__ | {args__}
by nefungoval podle přání, protože args__
bude odpovídat {12, 7, 3}
jako jediný argument .
Odpovědět
Existuje mnoho způsobů, jak to vyřešit. Přístup, který bych s největší pravděpodobností zvolil, lze ilustrovat na následujícím příkladu:
f[seqn : ___] := Module[{args = {seqn}}, Switch[args, {{___}}, "List of args", {_}, "One arg", {_, __}, "Two or more args", {}, "No args" ]] f[{x, y, z}] (* ==> "List of args" *) f[{x}] (* ==> "List of args" *) f[] (* ==> "No args" *) f[x] (* ==> "One arg" *) f[x, y, z] (* ==> "Two or more args" *)
Každá aplikace této techniky by samozřejmě nahradila zde zobrazené řetězce některými akce odpovídající jeho vlastním potřebám.
Dalším přístupem je psaní samostatných funkcí pro každý vzor argumentů, který chcete zpracovat:
g[args : {___}] := "List of args" g[] := "No args" g[arg_] := "One arg" g[arg_, rest__] := "Two or more args" g[{x, y, z}] (* ==> "List of args" *) g[{x}] (* ==> "List of args" *) g[] (* ==> "No args" *) g[x] (* ==> "One arg" *) g[x, y, z] (* ==> "Two or more args" *)
Komentáře
- Jaké jsou vaše důvody pro " s největší pravděpodobností " použití
Switch
přes více definic?Switch
je obvykle pomalejší a neměl by být používán bezdůvodně, IMHO. - @ Mr.Wizard. Používání
Switch
přitahuje můj smysl pro programování estetiky, protože organizuje všechny alternativy, aby s nimi bylo možné pracovat v jedné funkci. ' Obvykle ne všechno, co se týká rychlosti provádění, obvykle až tak dlouho, dokud nebude skutečně patrné pomalé provádění.
f[args___]:= f[{args}]
a poté zadejte definicif[{arg1_, arg2_,...}]
.