Sto cercando di riprodurre lAPI di una funzione (scritta in R) che accetta un numero arbitrario di argomenti e lo gestisce allo stesso modo in cui gestirebbe un singolo argomento che è un elenco di diversi set di dati.
Esiste un linguaggio di Mathematica che consente di definire una funzione in modo che:
f[ arg1, arg2, ..., argN ]
si comporti lo stesso di
f[ {arg1, arg2, ..., argN} ]
?
Commenti
Risposta
Come descritto da Andy Ross in un commento, puoi creare una definizione che preelabora gli argomenti in una forma canonica. Riportando il suo esempio semplicemente per illustrare la flessibilità:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
True
Questo metodo è utile per una preelaborazione più complicata, ma in casi semplici come questo è spesso più facile usare Alternatives
:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
True
Ricorda che quando utilizzando Alternatives
devi manualmente ordinare i pattern, poiché vengono provati in sequenza. Il pattern args__ | {args__}
non funzionerebbe come desiderato perché args__
corrisponderà a {12, 7, 3}
come singolo argomento .
Risposta
Ci sono molti modi per gestire questa situazione. Lapproccio che molto probabilmente adotterò può essere illustrato dal seguente esempio:
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" *)
Ovviamente, ogni applicazione di questa tecnica sostituirebbe le stringhe viste qui con alcune azione appropriata alle proprie esigenze.
Un altro approccio consiste nello scrivere funzioni separate per ogni modello di argomento che si desidera gestire:
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" *)
Commenti
- Qual è il tuo ragionamento per " molto probabilmente " utilizzando
Switch
su più definizioni?Switch
di solito è più lento e non dovrebbe essere utilizzato senza motivo, IMHO. - @ Mr.Wizard. Lutilizzo di
Switch
fa appello al mio senso dellestetica della programmazione perché organizza tutte le alternative in modo che possano essere gestite in ununica funzione. ' di solito non sono così preoccupato per la velocità di esecuzione, non finché lesecuzione lenta non diventa davvero evidente.
f[args___]:= f[{args}]
e quindi fornire la definizione dif[{arg1_, arg2_,...}]
.