Ik probeer de API van een functie (geschreven in R) te reproduceren die een willekeurig aantal argumenten accepteert en deze op dezelfde manier afhandelt als een enkel argument dat is een lijst met verschillende datasets.
Is er een Mathematica-idioom waarmee een functie kan worden gedefinieerd zodat:
f[ arg1, arg2, ..., argN ]
zich gedraagt hetzelfde als
f[ {arg1, arg2, ..., argN} ]
?
Reacties
Antwoord
Zoals beschreven door Andy Ross in een opmerking, kun je een definitie maken die het argument (en) voorbewerkt tot een canonieke vorm. Zijn voorbeeld omdraaien om flexibiliteit te illustreren:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
Waar
Deze methode is handig voor meer gecompliceerde voorverwerking, maar in eenvoudige gevallen zoals deze is het vaak gemakkelijker om Alternatives
te gebruiken:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
Waar
Houd er rekening mee dat wanneer door Alternatives
te gebruiken, moet u de patronen handmatig bestellen, want ze worden op volgorde geprobeerd. Het patroon args__ | {args__}
zou niet werken zoals gewenst omdat args__
overeenkomt met {12, 7, 3}
als een enkel argument .
Antwoord
Er zijn veel manieren om hiermee om te gaan. De benadering die ik hoogstwaarschijnlijk zou volgen, kan worden geïllustreerd door het volgende voorbeeld:
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" *)
Natuurlijk zou elke toepassing van deze techniek de hier getoonde strings vervangen door enkele actie passend bij zijn eigen behoeften.
Een andere benadering is om afzonderlijke functies te schrijven voor elk argumentpatroon dat u wilt behandelen:
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" *)
Opmerkingen
- Wat is uw redenering voor " hoogstwaarschijnlijk " met
Switch
over meerdere definities?Switch
is gewoonlijk langzamer en mag niet zonder reden worden gebruikt, IMHO. - @ Mr.Wizard. Het gebruik van
Switch
spreekt mijn gevoel voor programmeeresthetiek aan omdat het alle alternatieven organiseert zodat ze in één enkele functie kunnen worden behandeld. Ik ' ben meestal niet zo bezorgd over de uitvoeringssnelheid – niet voordat de trage uitvoering echt duidelijk wordt.
f[args___]:= f[{args}]
en geef vervolgens de definitie voorf[{arg1_, arg2_,...}]
.