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

Jeg prøver å reprodusere API for en funksjon (skrevet i R) som godtar et vilkårlig antall argumenter og håndterer det på samme måte som det ville håndtere et enkelt argument som er en liste over forskjellige datasett.

Er det et Mathematica-idiom som gjør det mulig å definere en funksjon slik at:

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

oppfører seg det samme som

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

?

Kommentarer

  • Du kan bare skrive f[args___]:= f[{args}] og deretter gi definisjonen for f[{arg1_, arg2_,...}].

Svar

Som beskrevet av Andy Ross i en kommentar, kan du lage en definisjon som forbehandler argumentet / argumentene til en kanonisk form. Å snu eksemplet hans bare for å illustrere fleksibilitet:

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

True

Denne metoden er nyttig for mer komplisert forbehandling, men i enkle tilfeller som dette er det ofte enklere å bruke Alternatives:

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

True

Vær oppmerksom på at når ved hjelp av Alternatives må du manuelt bestille mønstrene, for de blir prøvd i rekkefølge. Mønsteret args__ | {args__} fungerer ikke som ønsket fordi args__ vil matche {12, 7, 3} som et enkelt argument .

Svar

Det er mange måter å håndtere dette på. Tilnærmingen jeg mest sannsynlig vil ta kan illustreres med 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 av denne teknikken erstatte strengene som er sett her med noen handling som passer for sine egne behov.

En annen tilnærming er å skrive separate funksjoner 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

  • Hva er begrunnelsen din for " mest sannsynlig " ved hjelp av Switch over flere definisjoner? Switch er vanligvis tregere og bør ikke brukes uten grunn, IMHO.
  • @ Mr.Wizard. Å bruke Switch appellerer til min følelse av å programmere estetikk fordi den organiserer alle alternativene slik at de kan håndteres i en enkelt funksjon. Jeg ' Jeg pleier ikke å bekymre meg for kjøringshastighet – ikke før langsom kjøring blir virkelig tydelig.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *