2,954
edits
(Rip out the (wrong) model for unique.) |
(Simpler fix for length-1 case) |
||
(4 intermediate revisions by 3 users not shown) | |||
Line 72: | Line 72: | ||
== APL model == | == APL model == | ||
For [[Vector|vectors]] the following implementation based on [[Union]] can be used. It repeatedly adds cells of the argument to an accumulated unique vector <syntaxhighlight lang=apl inline>u</syntaxhighlight>, using Union so that duplicate cells are never added. | |||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
VecUnique ← { | |||
u ← 0↑⍵ | |||
u ⊣ {u∪←⍵}⍤¯1 ⊢1/⍵ | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]]}} | {{Works in|[[Dyalog APL]]}} | ||
The accumulation above resembles a [[reduction]]—in fact, it is a reverse [[insertion]] (reversing is necessary when using tolerant comparison as cells need to be added in order). The following implementation written with Reduce works for non-empty [[simple]] vectors in [[Nested array model|nested]] APLs because reduction is equivalent to insertion followed by [[Enclose]] on such vectors: | |||
It is extended to arbitrary rank inputs as follows: | <syntaxhighlight lang=apl> | ||
VecUnique ← {⊃∪⍨/⌽⍵} | |||
</syntaxhighlight> | |||
{{Works in|[[Dyalog APL]],[[ngn/apl]]}} | |||
It is extended to empty, nested, and arbitrary rank inputs as follows: | |||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
m ← { | m ← {0=≢⍵:⍵ ⋄ ↑,⊃∪⍨/⌽⊂¨⊂⍤¯1⊢⍵} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]]}} | {{Works in|[[Dyalog APL]]}} | ||
The guard checks for length zero because <syntaxhighlight lang=apl inline>∪⍨</syntaxhighlight> lacks an [[identity element]]. The [[Replicate]] call <syntaxhighlight lang=apl inline>1/⍵</syntaxhighlight> converts a scalar to a vector, and the encloses ensure that the array added by Union is always a scalar. | |||
If modelling the primitive via Union is not desirable due to how similar these two primitives are, it is possible to replace this particular usage of union (not generally, as it relies on the right argument being scalar) as follows: | |||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
m ← { | m ← {0=≢⍵:⍵ ⋄ ↑,⊃{⍺,(∧/⍺≢¨⍵)/⍵}⍨/⌽⊂¨⊂⍤¯1⊢⍵} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]]}} | {{Works in|[[Dyalog APL]]}} |