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

Jessaie de reproduire lAPI dune fonction (écrite en R) qui accepte un nombre arbitraire darguments et la gère de la même manière quelle traiterait un seul argument qui est une liste de différents ensembles de données.

Existe-t-il un idiome Mathematica qui permet de définir une fonction de sorte que:

f[ arg1, arg2, ..., argN ] 

se comporte identique à

f[ {arg1, arg2, ..., argN} ] 

?

Commentaires

  • Vous pouvez simplement écrire f[args___]:= f[{args}], puis fournissez la définition de f[{arg1_, arg2_,...}].

Réponse

Comme décrit par Andy Ross dans un commentaire, vous pouvez faire une définition qui pré-traite le ou les arguments sous une forme canonique. Renverser son exemple simplement pour illustrer sa flexibilité:

f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3] 

True

Cette méthode est utile pour un prétraitement plus compliqué, mais dans des cas simples comme celui-ci, elle est souvent plus facile à utiliser Alternatives:

g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3] 

Vrai

Sachez que lorsque en utilisant Alternatives vous devez manuellement ordonner les motifs, car ils sont essayés en séquence. Le modèle args__ | {args__} ne fonctionnerait pas comme vous le souhaitez car args__ correspondra à {12, 7, 3} comme argument unique .

Réponse

Il existe de nombreuses façons de gérer cela. Lapproche que je prendrais très probablement peut être illustrée par lexemple suivant:

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" *) 

Bien sûr, chaque application de cette technique remplacerait les chaînes vues ici par des action appropriée à ses propres besoins.

Une autre approche consiste à écrire des fonctions séparées pour chaque modèle dargument que vous souhaitez gérer:

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" *) 

Commentaires

  • Quel est votre raisonnement pour " le plus probable " en utilisant Switch sur plusieurs définitions? Switch est généralement plus lent et ne doit pas être utilisé sans raison, à mon humble avis.
  • @ Mr.Wizard. Utiliser Switch fait appel à mon sens de lesthétique de la programmation car il organise toutes les alternatives pour quelles puissent être traitées dans une seule fonction. Je ' je ne suis généralement pas très préoccupé par la vitesse dexécution – pas avant que la lenteur de lexécution ne devienne vraiment évidente.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *