4,494
edits
m (Text replacement - "<source" to "<syntaxhighlight") |
m (Text replacement - "</source>" to "</syntaxhighlight>") Tags: Mobile edit Mobile web edit |
||
Line 7: | Line 7: | ||
∪ 'Mississippi' | ∪ 'Mississippi' | ||
Misp | Misp | ||
</ | </syntaxhighlight> | ||
It works on nested arrays as well: | It works on nested arrays as well: | ||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
Line 14: | Line 14: | ||
│CAT│DOG│DUCK│ | │CAT│DOG│DUCK│ | ||
└───┴───┴────┘ | └───┴───┴────┘ | ||
</ | </syntaxhighlight> | ||
In some languages, such as [[J]] and [[Dyalog APL 17.0]] and later, Unique applies to the [[major cells]] of an array, including those with rank greater than 1: | In some languages, such as [[J]] and [[Dyalog APL 17.0]] and later, Unique applies to the [[major cells]] of an array, including those with rank greater than 1: | ||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
Line 33: | Line 33: | ||
1 3 3 | 1 3 3 | ||
2 3 6 | 2 3 6 | ||
</ | </syntaxhighlight> | ||
== Definition == | == Definition == | ||
Line 59: | Line 59: | ||
x∊1↑x ⍝ ...which wouldn't happen if the last were excluded | x∊1↑x ⍝ ...which wouldn't happen if the last were excluded | ||
1 1 0 | 1 1 0 | ||
</ | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]]}} | {{Works in|[[Dyalog APL]]}} | ||
== History == | == History == | ||
The function Nub was proposed in 1978 by [[Ken Iverson|Iverson]] as one of a collection of set functions (including [[Union]], [[Intersection]], and [[Difference]]) with the symbol <syntaxhighlight lang=apl inline>∪</ | The function Nub was proposed in 1978 by [[Ken Iverson|Iverson]] as one of a collection of set functions (including [[Union]], [[Intersection]], and [[Difference]]) with the symbol <syntaxhighlight lang=apl inline>∪</syntaxhighlight> and definition <syntaxhighlight lang=apl inline>∪w</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>((⍳⍴w)=w⍳w)/w←,w</syntaxhighlight>.<ref>[[Ken Iverson|Iverson, Ken]]. [https://www.jsoftware.com/papers/opfns.htm ''Operators and Functions'']. IBM Research Report #RC7091. 1978-04-26.</ref> It was implemented as part of [[STSC]]'s [[NARS]] in 1981 with the name Unique and the same definition, except that the argument was restricted to be a vector or scalar.<ref>Cheney, Carl. ''APL*PLUS Nested Arrays Reference Manual. [[STSC]] Inc. 1981.</ref> Later APLs such as [[Dyalog APL]] generally adopted this version of the primitive, and it is featured in the [[ISO/IEC 13751:2001]] standard. Dyalog extended Unique to higher-rank arrays in [[Dyalog APL 17.0]], following the much earlier extension made by [[J]]. | ||
Iverson continued to refine his definition of Nub. He included it in his [[Rationalized APL]] specification with no changes in 1983, but modified it to work on [[major cell]]s (thus aligning it with [[leading axis theory]]) in his 1987 [[A Dictionary of APL]]. Iverson's dictionary also changed the symbol for Nub to <syntaxhighlight lang=apl inline>↑</ | Iverson continued to refine his definition of Nub. He included it in his [[Rationalized APL]] specification with no changes in 1983, but modified it to work on [[major cell]]s (thus aligning it with [[leading axis theory]]) in his 1987 [[A Dictionary of APL]]. Iverson's dictionary also changed the symbol for Nub to <syntaxhighlight lang=apl inline>↑</syntaxhighlight>, added the functions [[Nub Sieve]] (<syntaxhighlight lang=apl inline>≠</syntaxhighlight>) and [[Nub in]] (<syntaxhighlight lang=apl inline>=</syntaxhighlight>), and defined Nub in terms of Nub Sieve. These definitions were adopted by [[IPSA]] in the [[SHARP APL]] successor [[SAX]]. [[J]] uses similar definitions: its Nub-related functions are Nub (<syntaxhighlight lang=j inline>~.</syntaxhighlight>), [[Nub Sieve]] (<syntaxhighlight lang=j inline>~:</syntaxhighlight>), and [[Self-classify]] (<syntaxhighlight lang=j inline>=</syntaxhighlight>). However, Self-classify is indicated as deprecated in J's NuVoc because its result can be much larger than its argument. | ||
[[A+]] does not include Unique or any related functions, but [[K]]'s function range (<code>?</code>) gives the unique elements of a list argument. In later versions it is called "distinct" or "unique". While APLs allow a [[scalar]] argument ([[scalar rank extension]]), K gives a [[RANK ERROR]] if the argument is not a list. | [[A+]] does not include Unique or any related functions, but [[K]]'s function range (<code>?</code>) gives the unique elements of a list argument. In later versions it is called "distinct" or "unique". While APLs allow a [[scalar]] argument ([[scalar rank extension]]), K gives a [[RANK ERROR]] if the argument is not a list. | ||
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</ | 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 ← { | VecUnique ← { | ||
Line 78: | Line 78: | ||
u ⊣ {u∪←⍵}⍤¯1 ⊢1/⍵ | u ⊣ {u∪←⍵}⍤¯1 ⊢1/⍵ | ||
} | } | ||
</ | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]]}} | {{Works in|[[Dyalog APL]]}} | ||
The accumulation above resembles a [[reduction]]—in fact, it is a reverse [[insertion]]. The following implementation written with Reduce works for [[simple]] vectors in [[Nested array model|nested]] APLs because reduction is equivalent to insertion followed by [[Enclose]] on such vectors: | The accumulation above resembles a [[reduction]]—in fact, it is a reverse [[insertion]]. The following implementation written with Reduce works for [[simple]] vectors in [[Nested array model|nested]] APLs because reduction is equivalent to insertion followed by [[Enclose]] on such vectors: | ||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
VecUnique ← {⊃∪⍨/⌽⍵} | VecUnique ← {⊃∪⍨/⌽⍵} | ||
</ | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]],[[ngn/apl]]}} | {{Works in|[[Dyalog APL]],[[ngn/apl]]}} | ||
It can be modified to obtain a full model for Unique by enclosing enough times, and converting scalars to vectors with [[Replicate]] at the end: | It can be modified to obtain a full model for Unique by enclosing enough times, and converting scalars to vectors with [[Replicate]] at the end: | ||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
Unique ← {1/↑↑⌽∪/⌽⊂∘⊂⍤¯1⊢⍵} | Unique ← {1/↑↑⌽∪/⌽⊂∘⊂⍤¯1⊢⍵} | ||
</ | </syntaxhighlight> | ||
{{Works in|[[Dyalog APL]]}} | {{Works in|[[Dyalog APL]]}} | ||
While the model <syntaxhighlight lang=apl inline>{((⍳≢⍵)=(⍵⍳⍵))⌿⍵}</ | While the model <syntaxhighlight lang=apl inline>{((⍳≢⍵)=(⍵⍳⍵))⌿⍵}</syntaxhighlight>, based on [[Nub Sieve]], is often described as an implementation of Unique, it does not correctly handle [[tolerant comparison]].<ref>Hui, Roger. [https://dyalog.tv/Dyalog17/?v=fPWky9IOG40 Tolerant Unique]. [[Dyalog '17]].</ref> A correct implementation of Nub Sieve could be used to implement Unique, but writing such an implementation is no easier than implementing Unique directly. | ||
== Properties == | == Properties == | ||
Line 105: | Line 105: | ||
* [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Unique.htm Dyalog] | * [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Unique.htm Dyalog] | ||
* [http://microapl.com/apl_help/ch_020_020_392.htm APLX] | * [http://microapl.com/apl_help/ch_020_020_392.htm APLX] | ||
* [https://www.jsoftware.com/help/dictionary/d221.htm J Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/tildedot J NuVoc] (as <syntaxhighlight lang=apl inline>~.</ | * [https://www.jsoftware.com/help/dictionary/d221.htm J Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/tildedot J NuVoc] (as <syntaxhighlight lang=apl inline>~.</syntaxhighlight>) | ||
* [https://mlochbaum.github.io/BQN/doc/selfcmp.html#deduplicate BQN] (as <code>⍷</code>) | * [https://mlochbaum.github.io/BQN/doc/selfcmp.html#deduplicate BQN] (as <code>⍷</code>) | ||