Ich versuche, die API einer Funktion (in R geschrieben) zu reproduzieren, die eine beliebige Anzahl von Argumenten akzeptiert und sie genauso behandelt wie ein einzelnes Argument ist eine Liste verschiedener Datensätze.
Gibt es eine Mathematica-Redewendung, mit der eine Funktion so definiert werden kann, dass:
f[ arg1, arg2, ..., argN ]
sich verhält das gleiche wie
f[ {arg1, arg2, ..., argN} ]
?
Kommentare
- Sie könnten einfach schreiben
f[args___]:= f[{args}]
und geben Sie dann die Definition fürf[{arg1_, arg2_,...}]
an.
Antwort
Wie von Andy Ross in einem Kommentar beschrieben, können Sie eine Definition erstellen, die die Argumente in eine kanonische Form vorverarbeitet. Drehen Sie sein Beispiel einfach um, um die Flexibilität zu veranschaulichen:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
True
Diese Methode ist nützlich für eine kompliziertere Vorverarbeitung, aber in einfachen Fällen wie diesen ist es oft einfacher, Alternatives
:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
True
Beachten Sie, dass wann Mit Alternatives
müssen Sie die Muster manuell bestellen, da sie nacheinander versucht werden. Das Muster args__ | {args__}
würde nicht wie gewünscht funktionieren, da args__
mit {12, 7, 3}
als einzelnes Argument übereinstimmt .
Antwort
Es gibt viele Möglichkeiten, damit umzugehen. Der Ansatz, den ich höchstwahrscheinlich verfolgen würde, kann anhand des folgenden Beispiels veranschaulicht werden:
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" *)
Natürlich würde jede Anwendung dieser Technik die hier gezeigten Zeichenfolgen durch einige ersetzen Aktion, die den eigenen Anforderungen entspricht.
Ein anderer Ansatz besteht darin, separate Funktionen für jedes Argumentmuster zu schreiben, das Sie verarbeiten möchten:
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" *)
Kommentare
- Was ist Ihre Begründung für " höchstwahrscheinlich " mit
Switch
über mehrere Definitionen?Switch
ist normalerweise langsamer und sollte meiner Meinung nach nicht ohne Grund verwendet werden. - @ Mr.Wizard. Die Verwendung von
Switch
spricht meinen Sinn für Programmierästhetik an, da alle Alternativen so organisiert sind, dass sie in einer einzigen Funktion behandelt werden können. Ich ' bin normalerweise nicht allzu besorgt über die Ausführungsgeschwindigkeit – erst wenn die langsame Ausführung wirklich offensichtlich wird.