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

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

  • Du kunne bare skrive f[args___]:= f[{args}] og angiv derefter definitionen for f[{arg1_, arg2_,...}].

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.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *