f [arg1, arg2, …, argN] vs. f [{arg1, arg2, …, argN}] (Português)

Estou tentando reproduzir a API de uma função (escrita em R) que aceita um número arbitrário de argumentos e o trata da mesma maneira que faria com um único argumento que é uma lista de conjuntos de dados diferentes.

Existe um idioma do Mathematica que permite que uma função seja definida para que:

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

se comporte o mesmo que

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

?

Comentários

  • Você poderia simplesmente escrever f[args___]:= f[{args}] e, em seguida, forneça a definição para f[{arg1_, arg2_,...}].

Resposta

Conforme descrito por Andy Ross em um comentário, você pode fazer uma definição que pré-processe o (s) argumento (s) em uma forma canônica. Virando seu exemplo simplesmente para ilustrar a flexibilidade:

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

Verdadeiro

Este método é útil para um pré-processamento mais complicado, mas em casos simples como este, geralmente é mais fácil de usar Alternatives:

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

Verdadeiro

Esteja ciente de que quando usando Alternatives você deve ordenar manualmente os padrões, pois eles são testados em sequência. O padrão args__ | {args__} não funcionaria como desejado porque args__ corresponderá a {12, 7, 3} como um único argumento .

Resposta

Existem muitas maneiras de lidar com isso. A abordagem que eu provavelmente faria pode ser ilustrada pelo seguinte exemplo:

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

Claro, cada aplicação desta técnica substituiria as strings vistas aqui por alguns ação apropriada às suas próprias necessidades.

Outra abordagem é escrever funções separadas para cada padrão de argumento que você deseja manipular:

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

Comentários

  • Qual é o seu raciocínio para " provavelmente " usando Switch em várias definições? Switch geralmente é mais lento e não deve ser usado sem motivo, IMHO.
  • @ Mr.Wizard. Usar Switch apela ao meu senso de estética de programação porque organiza todas as alternativas para que possam ser tratadas em uma única função. Eu ' m geralmente não me preocupo muito com a velocidade de execução – não até que a execução lenta se torne realmente evidente.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *