问题
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:
- disclose the scalar:
⊃⍵
- apply the function:
f⊃⍵
- enclose the result:
⊂f⊃⍵
A similar expression applies for the dyadic case, x f¨y
, but we need to:
- disclose both scalars:
(⊃⍺)
…(⊃⍵)
- apply the function:
(⊃⍺)f(⊃⍵)
- 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