f [arg1, arg2, …, argN] vs. f [{arg1, arg2, …, argN}] (Română)

Î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

  • Ai putea scrie f[args___]:= f[{args}] și apoi furnizați definiția pentru f[{arg1_, arg2_,...}].

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ă.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *