Încerc să reproduc API-ul unei funcții (scrisă în R) care acceptă un număr arbitrar de argumente și o gestionează în același mod în care ar gestiona un singur argument care este o listă de seturi de date diferite.
Există un idiom Mathematica care permite definirea unei funcții astfel încât:
f[ arg1, arg2, ..., argN ]
să se comporte la fel ca
f[ {arg1, arg2, ..., argN} ]
?
Comentarii
Răspundeți
După cum este descris de Andy Ross într-un comentariu, puteți face o definiție care preprocesează argumentele într-o formă canonică. Întorcându-și exemplul pentru a ilustra flexibilitatea:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
Adevărat
Această metodă este utilă pentru o prelucrare mai complicată, dar în cazuri simple precum acesta este adesea mai ușor de utilizat Alternatives
:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
Adevărat
Rețineți că atunci când folosind Alternatives
trebuie să manual comandați modelele, deoarece acestea sunt încercate în ordine. Șablonul args__ | {args__}
nu ar funcționa așa cum se dorește, deoarece args__
se va potrivi cu {12, 7, 3}
ca un singur argument .
Răspuns
Există multe modalități de a rezolva acest lucru. Abordarea pe care aș lua-o cel mai probabil poate fi ilustrată de următorul exemplu:
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" *)
Desigur, fiecare aplicație a acestei tehnici ar înlocui șirurile văzute aici cu unele acțiune adecvată propriilor sale nevoi.
O altă abordare este de a scrie funcții separate pentru fiecare model de argument pe care doriți să îl gestionați:
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" *)
Comentarii
- Care este raționamentul dvs. pentru " cel mai probabil " folosind
Switch
peste mai multe definiții?Switch
este, de obicei, mai lent și nu trebuie utilizat fără motiv, IMHO. - @ Mr.Wizard. Folosirea
Switch
face apel la simțul meu de estetică a programării, deoarece organizează toate alternativele, astfel încât acestea să poată fi tratate într-o singură funcție. ' De obicei, nu sunt preocupat de viteza de execuție – până când execuția lentă devine cu adevărat evidentă.
f[args___]:= f[{args}]
și apoi furnizați definiția pentruf[{arg1_, arg2_,...}]
.