Идиоматический способ выбора из матрицы на основе значения - PullRequest
1 голос
/ 06 октября 2019

Следующая employee матрица имен и адресов электронной почты наглядно показывает, что адрес электронной почты bob - bob@example.com.

┌───────┬─────────────────────┐
│alice  │alice@example.com    │
├───────┼─────────────────────┤
│bob    │bob@example.com      │
├───────┼─────────────────────┤
│charlie│charlie47@example.com│
└───────┴─────────────────────┘

Но как мне программным образом получить доступ к адресу электронной почты на основе заданного значения в столбце 1? Лучший подход, который я нашел до сих пор, это

(⊂'bob') {(⍵[;1]⍳⍺) 2 ⌷⍵} employees

Это работает , но довольно многословно - я чувствую, что, должно быть, мне не хватает гораздо более простого способа сделать то, что я бы сделалпредставьте, что это довольно распространенное явление.

Какие-нибудь советы о том, что мне не хватает?

1 Ответ

2 голосов
/ 06 октября 2019

Существуют различные способы формулирования вашей функции, но все они совпадают с этими треками:

(⊂'bob'){(⍺⍳⍨⊣/⍵)⌷⊢/⍵}employee

Однако использование функции может быть слишком большой абстракцией, так как вы можете захотеть использовать индекс дляизвлечение из другой таблицы;

employee[employee[;1]⍳⊂'bob';2]

Для удобства чтения вы можете назвать ваши столбцы:

(name email)←⍳2
employee[employee[;name]⍳⊂'bob';email]

Но на самом деле классический способ - использовать отдельный массив для каждого столбца:

(name email)←↓⍉employee
email⌷⍨name⍳⊂'bob'

Для большей организации (избегая загрязнения рабочего пространства одним именем на столбец) вы можете собрать их в пространстве имен:

(Employee←⎕NS⍬).(name email)←↓⍉employee
Employee.(email⌷⍨name⍳⊂)'bob'

Если вы хотите добиться максимальной производительности базы данныхВы должны назначить каждому столбцу фиксированную ширину поля:

(name email)←10 30(⊢↑⍨⊢∘≢,⊣)¨↑¨↓⍉employee
email⌷⍨name⍳10↑'bob'

Конечно, вы можете поместить их в пространство имен, но вы также можете сохранить столбцы как элементы вектора. Это называется инвертированной таблицей .

employeeIT←10 30(⊢↑⍨⊢∘≢,⊣)¨↑¨↓⍉employee
(name email)←⍳2
(email⊃employeeIT)⌷⍨(names⊃employeeIT)⍳10↑'bob'

Еще один способ достижения высокой производительности - связать список имен с , который заставляет APL генерировать хеш-таблицу. Фактически, вы можете также связать список адресов электронной почты с индексацией и использовать полностью функциональный подход:

(name email)←↓⍉employee
Name←name∘⍳
Email←⌷∘email
Email Name ⊂'bob'
...