f [arg1, arg2, …, argN] gegen f [{arg1, arg2, …, argN}]

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ür f[{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.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.