f [arg1, arg2, …, argN] vs. f [{arg1, arg2, …, argN}] (Svenska)

Jag försöker återge API: et för en funktion (skriven i R) som accepterar ett godtyckligt antal argument och hanterar det på samma sätt som det skulle hantera ett enda argument som är en lista över olika datamängder.

Finns det ett Mathematica-idiom som gör att en funktion kan definieras så att:

f[ arg1, arg2, ..., argN ] 

beter sig samma som

f[ {arg1, arg2, ..., argN} ] 

?

Kommentarer

  • Du kan bara skriva f[args___]:= f[{args}] och ange sedan definitionen för f[{arg1_, arg2_,...}].

Svar

Som beskrivs av Andy Ross i en kommentar kan du göra en definition som förbehandlar argumenten till en kanonisk form. Att vända på hans exempel för att illustrera flexibilitet:

f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3] 

True

Denna metod är användbar för mer komplicerad förbehandling, men i enkla fall som detta är det ofta lättare att använda Alternatives:

g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3] 

True

Var medveten om att när med Alternatives måste du manuellt beställa mönstren, för de prövas i följd. Mönstret args__ | {args__} fungerar inte som önskat eftersom args__ matchar {12, 7, 3} som ett enda argument .

Svar

Det finns många sätt att hantera detta. Det tillvägagångssätt som jag sannolikt skulle ta kan illustreras med följande exempel:

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" *) 

Naturligtvis skulle varje tillämpning av denna teknik ersätta strängarna som ses här med några åtgärd som passar sina egna behov.

Ett annat tillvägagångssätt är att skriva separata funktioner för varje argumentmönster du vill hantera:

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" *) 

Kommentarer

  • Vad resonerar du för " troligtvis " med Switch över flera definitioner? Switch är vanligtvis långsammare och bör inte användas utan anledning, IMHO.
  • @ Mr.Wizard. Att använda Switch tilltalar min känsla av att programmera estetik eftersom den organiserar alla alternativ så att de kan hanteras i en enda funktion. Jag ' Jag brukar inte alla som berör exekveringshastighet – inte förrän långsam körning blir riktigt tydlig.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *