How to use rank operator instead of each in APL

陌路散爱 提交于 2019-12-22 10:43:46

问题


I have

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

and need following output

 defghijk20down  defghijk30down  defghijk50down 

I can do it with:

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

but please help me to write without each operator but using rank

I use Dyalog APL, but please do not use trains.

Thank you


回答1:


Expressions using Each, like f¨x, can be expressed in terms of Rank as {⊂f⊃⍵}⍤0⊢x (note that is to separate the array right operand, 0 from the array right argument x). In other words, on the scalars of the argument we:

  1. disclose the scalar: ⊃⍵
  2. apply the function: f⊃⍵
  3. enclose the result: ⊂f⊃⍵

A similar expression applies for the dyadic case, x f¨y, but we need to:

  1. disclose both scalars: (⊃⍺)(⊃⍵)
  2. apply the function: (⊃⍺)f(⊃⍵)
  3. enclose the result: ⊂(⊃⍺)f(⊃⍵)

This gives us x{⊂(⊃⍺)f(⊃⍵)}⍤0⊢y. We can thus use Rank to build our own Each operator which allows both monadic and dyadic application of the derived function:

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

Alternatively, we can substitute the two simpler equivalences into your expression:

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

Notice that we are enclosing texttoadd so it becomes scalar, and then we use ⍤0 to address that entire scalar, only to disclose it again. Instead, we can use ⍤0 1 to say that want to use the entire vector right argument when applying the function, which in turn doesn't need to disclose its right argument:

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

rfikv and ¯10 are a simple scalars, so disclosing them has no effect:

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

dummytxt is in the same situation as texttoadd above, but as left argument, so we can skip the enclose-disclose and ask Rank to use the entire vector left argument; ⍤1 0:

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

This is about as simple as it gets using a general method. However, if we instead observe that the only non-scalar is rfikv, we can treat dummytxt and texttoadd as global constants and express the entire thing as a single ⍤0 function application on rfikv:

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

Of course, Each can do this too:

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


来源:https://stackoverflow.com/questions/58247544/how-to-use-rank-operator-instead-of-each-in-apl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!