2016-05-15 10 views
3

Я играю с итерируемыми и понимания в Джулию и пытались закодировать простую задачу: найти все пары чисел меньше 10, произведение которых меньше 10. Это была моя первая попытка:фильтр коллекцию кортежей

solution = filter((a,b)->a*b<10, product(1:10, 1:10)) 
collect(solution) 

но я получил ошибку «неправильное количество аргументов». Это отчасти ожидается, потому что анонимная функция внутри фильтра ожидает два аргумента, но получает один кортеж. Я знаю, что могу сделать

solution = filter(p->p[1]*p[2]<10, product(1:10, 1:10)) 

, но это не выглядит хорошо, как выше. Есть ли способ, которым я могу сказать, что (a, b) является аргументом типа tuple и использовать в первом примере что-то похожее на синтаксис?

+2

Для этого конкретного примера вы также можете настроить тело функции: 'a -> prod (a) <10', но пример' @ tup' - довольно аккуратная идея. – jverzani

ответ

4

Я не думаю, что есть способ сделать именно так, как вы хотели бы, но вот некоторые альтернативы вы могли бы рассмотреть для анонимной функции:

x->let (a,b)=x; a*b<10 end 
x->((a,b)=x; a*b<10) 

Они, конечно, могут быть сделаны в макросы, если это вам нравится:

macro tup(ex) 
    @assert ex.head == :(->) 
    @assert ex.args[1].head == :tuple 
    arg = gensym() 
    quote 
     $arg -> ($(ex.args[1]) = $arg; $(ex.args[2])) 
    end 
end 

Тогда @tup (a, b) -> a * b < 10 будет делать как вам нравится.

Metaprogramming в Julia довольно полезен и распространен для ситуаций, когда вы делаете что-то снова и снова и хотели бы использовать специальный синтаксис для него. Но я бы избегал такого метапрограммирования, если бы это было одноразовое дело, потому что добавление нового синтаксиса означает изучение нового синтаксиса и делает код более трудным для чтения.