Jeg forsøger at gengive APIen til en funktion (skrevet i R), der accepterer et vilkårligt antal argumenter og håndterer det på samme måde, som det ville håndtere et enkelt argument, der er en liste over forskellige datasæt.
Er der et Mathematica-idiom, der gør det muligt at definere en funktion, så:
f[ arg1, arg2, ..., argN ]
opfører sig det samme som
f[ {arg1, arg2, ..., argN} ]
?
Kommentarer
Svar
Som beskrevet af Andy Ross i en kommentar, kan du lave en definition, der forbehandler argumenterne til en kanonisk form. Vender sit eksempel rundt blot for at illustrere fleksibilitet:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
Sandt
Denne metode er nyttig til mere kompliceret forbehandling, men i simple tilfælde som dette er det ofte lettere at bruge Alternatives
:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
Sandt
Vær opmærksom på, at når ved hjælp af Alternatives
skal du manuelt bestille mønstrene, for de prøves i rækkefølge. Mønsteret args__ | {args__}
fungerer ikke som ønsket, fordi args__
matcher {12, 7, 3}
som et enkelt argument .
Svar
Der er mange måder at håndtere dette på. Den tilgang, jeg højst sandsynligt vil følge, kan illustreres ved følgende eksempel:
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" *)
Selvfølgelig vil hver anvendelse af denne teknik erstatte strengene, der ses her med nogle handling, der passer til dets egne behov.
En anden tilgang er at skrive separate funktioner for hvert argumentmønster, du vil håndtere:
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
- Hvad er din begrundelse for " sandsynligvis " ved hjælp af
Switch
over flere definitioner?Switch
er normalt langsommere og bør ikke bruges uden grund, IMHO. - @ Mr.Wizard. Brug af
Switch
appellerer til min følelse af programmering af æstetik, fordi det organiserer alle alternativer, så de kan behandles i en enkelt funktion. Jeg ' Jeg plejer ikke at bekymre mig om eksekveringshastighed – først når langsom udførelse bliver virkelig tydelig.
f[args___]:= f[{args}]
og angiv derefter definitionen forf[{arg1_, arg2_,...}]
.