Я в настоящее время учу захватывающий язык программирования J, но одна вещь, которую я не смог выяснить, состоит в том, как отфильтровать список.
Предположим, что у меня есть произвольный список 3 2 2 7 7 2 9
и я хочу удалить 2 с, но оставлять без изменений все остальное, т.е. мой результат было бы 3 7 7 9
. Как же я делаю это?
2 (~: # ]) 3 2 2 7 7 2 9
3 7 7 9
У меня есть для вас ответ, но прежде вам следует ознакомиться с некоторыми деталями. Итак, приступим.
В J есть два типа глаголов: монады и диады. Первые принимают только один параметр, вторые - два.
Например, передача единственного аргумента монадическому глаголу #
, называемому tally, подсчитывает количество элементов в списке:
# 3 2 2 7 7 2 9
7
Глагол #
, принимающий два аргумента (слева и справа), называется copy, он является диадическим и используется для копирования элементов из правого списка столько раз, сколько задано соответствующими элементами в левом списке (в списке также может быть единственный элемент):
0 0 0 3 0 0 0 # 3 2 2 7 7 2 9
7 7 7
В J есть понятие fork, которое представляет собой серию из 3 глаголов, применяемых к своим аргументам, диадически или монадически.
Вот диаграмма вида вилки, которую я использовал в первом фрагменте:
x (F G H) y
G
/ \
F H
/ \ / \
x y x y
Она описывает порядок, в котором глаголы применяются к своим аргументам. Таким образом, эти применения имеют место:
2 ~: 3 2 2 7 7 2 9
1 0 0 1 1 0 1
В данном примере ~:
(not equal) является диадическим и приводит к списку булевых значений, которые истинны, когда аргумент не равен 2
. Это было применение F
в соответствии с диаграммой.
Следующее применение - H
:
2 ] 3 2 2 7 7 2 9
3 2 2 7 7 2 9
]
(identity) может быть монадой или диадой, но всегда возвращает правый аргумент, переданный глаголу (есть противоположный глагол, [
, который возвращает... Да, левый аргумент! :)
Пока все хорошо. F
и H
после применения вернули эти значения соответственно:
1 0 0 1 1 0 1
3 2 2 7 7 2 9
Осталось выполнить только применение глагола G
.
Как я уже отмечал ранее, глагол #
, который является диадическим (принимает два аргумента), позволяет нам дублировать элементы из правого аргумента столько раз, сколько указано в соответствующих позициях в левом аргументе. Отсюда:
1 0 0 1 1 0 1 # 3 2 2 7 7 2 9
3 7 7 9
Мы только что получили список, отфильтрованный из 2
.
Немного другого вида fork, hook и другие примитивы (включая вышеупомянутые) описаны в этих двух документах:
Другие полезные источники информации - сайт Jsoftware с их wiki и несколько архивов почтовых списков в интернетах.