f [arg1, arg2, …, argN] vs. f [{arg1, arg2, …, argN}] (Čeština)

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

  • Stačí napsat f[args___]:= f[{args}] a poté zadejte definici f[{arg1_, arg2_,...}].

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í.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *