Как использовать оператор ранга вместо каждого в APL - PullRequest
3 голосов
/ 05 октября 2019

У меня есть

dummytxt←'abcdefghijk'
texttoadd←'down'
rfikv←20 30 50

и мне нужен следующий вывод

 defghijk20down  defghijk30down  defghijk50down 

Я могу сделать это с помощью:

scenv←(¯10↑¨(⊂dummytxt),¨⍕¨rfikv),¨⊂texttoadd

, но, пожалуйста, помогите мне писать без каждогооператор, но использующий ранг

Я использую Dyalog APL, но, пожалуйста, не пользуйтесь поездами.

Спасибо

1 Ответ

1 голос
/ 05 октября 2019

Выражения с использованием Каждое , например f¨x, может быть выражено в виде Rank как {⊂f⊃⍵}⍤0⊢x (обратите внимание, что предназначен для разделения правого операнда массива, 0 из аргумента массива справа x). Другими словами, в скалярах аргумента мы:

  1. раскрываем скаляр: ⊃⍵
  2. применяем функцию: f⊃⍵
  3. заключаем в результат: ⊂f⊃⍵

Аналогичное выражение применимо для двоичного случая, x f¨y, но нам нужно:

  1. раскрыть оба скаляра: (⊃⍺)(⊃⍵)
  2. применить функцию: (⊃⍺)f(⊃⍵)
  3. заключить результат: ⊂(⊃⍺)f(⊃⍵)

Это дает нам x{⊂(⊃⍺)f(⊃⍵)}⍤0⊢y. Таким образом, мы можем использовать Rank для создания собственного каждого оператора, который позволяет как монадическое, так и двоичное применение производной функции:

      Each←{⍺←⊢ ⋄ ⍺ ⍺⍺{×⎕NC'⍺':⊂(⊃⍺)⍺⍺(⊃⍵) ⋄ ⊂⍺⍺⊃⍵}⍤0⊢⍵}
      (¯10↑Each(⊂dummytxt),Each⍕Each rfikv),Each⊂texttoadd
 defghijk20down  defghijk30down  defghijk50down 

В качестве альтернативы, мы можем заменитьдва простых эквивалента в вашем выражении:

      (¯10{⊂(⊃⍺)↑(⊃⍵)}⍤0⊢(⊂dummytxt){⊂(⊃⍺),(⊃⍵)}⍤0{⊂⍕⊃⍵}⍤0⊢rfikv){⊂(⊃⍺),(⊃⍵)}⍤0⊂texttoadd
 defghijk20down  defghijk30down  defghijk50down 

Обратите внимание, что мы заключаем texttoadd, так что оно становится скалярным, а затем мы используем ⍤0 для обращения ко всему скаляру, только чтобы раскрыть его снова. Вместо этого мы можем использовать ⍤0 1, чтобы сказать, что хотите использовать весь векторный правильный аргумент при применении функции, которая в свою очередь не должна раскрывать ее правильный аргумент:

      (¯10{⊂(⊃⍺)↑(⊃⍵)}⍤0⊢(⊂dummytxt){⊂(⊃⍺),(⊃⍵)}⍤0{⊂⍕⊃⍵}⍤0⊢rfikv){⊂(⊃⍺),⍵}⍤0 1⊢texttoadd
 defghijk20down  defghijk30down  defghijk50down 

rfikv и ¯10 являются простыми скалярами, поэтому их раскрытие не имеет никакого эффекта:

      (¯10{⊂⍺↑(⊃⍵)}⍤0⊢(⊂dummytxt){⊂(⊃⍺),(⊃⍵)}⍤0{⊂⍕⍵}⍤0⊢rfikv){⊂(⊃⍺),⍵}⍤0 1⊢texttoadd
 defghijk20down  defghijk30down  defghijk50down 

dummytxt находится в той же ситуации, что и texttoadd выше, но в качестве левого аргумента, поэтомумы можем пропустить enclose-disclose и попросить Rank использовать весь левый аргумент vector;⍤1 0:

      (¯10{⊂⍺↑(⊃⍵)}⍤0⊢dummytxt{⊂⍺,(⊃⍵)}⍤1 0{⊂⍕⍵}⍤0⊢rfikv){⊂(⊃⍺),⍵}⍤0 1⊢texttoadd
 defghijk20down  defghijk30down  defghijk50down 

Это почти так же просто, как при использовании общего метода. Однако если мы вместо этого заметим, что единственным нескалярным является rfikv, мы можем рассматривать dummytxt и texttoadd как глобальные константы и выражать все это как одно приложение функции ⍤0 в rfikv:

      {⊂(¯10↑dummytxt,⍕⍵),texttoadd}⍤0⊢rfikv
 defghijk20down  defghijk30down  defghijk50down 

Конечно, Каждый может сделать это тоже:

      {(¯10↑dummytxt,⍕⍵),texttoadd}¨rfikv
 defghijk20down  defghijk30down  defghijk50down 
...