Unique: Difference between revisions

Jump to navigation Jump to search
171 bytes added ,  10:58, 11 September 2022
m
Text replacement - "</source>" to "</syntaxhighlight>"
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
</source>
</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│
└───┴───┴────┘
└───┴───┴────┘
</source>
</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
</source>
</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
</source>
</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>∪</source> and definition <syntaxhighlight lang=apl inline>∪w</source> {{←→}} <syntaxhighlight lang=apl inline>((⍳⍴w)=w⍳w)/w←,w</source>.<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]].
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>↑</source>, added the functions [[Nub Sieve]] (<syntaxhighlight lang=apl inline>≠</source>) and [[Nub in]] (<syntaxhighlight lang=apl inline>=</source>), 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>~.</source>), [[Nub Sieve]] (<syntaxhighlight lang=j inline>~:</source>), and [[Self-classify]] (<syntaxhighlight lang=j inline>=</source>). However, Self-classify is indicated as deprecated in J's NuVoc because its result can be much larger than its argument.
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</source>, using Union so that duplicate cells are never added.
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/⍵
}
}
</source>
</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 ← {⊃∪⍨/⌽⍵}
</source>
</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⊢⍵}
</source>
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
{{Works in|[[Dyalog APL]]}}


While the model <syntaxhighlight lang=apl inline>{((⍳≢⍵)=(⍵⍳⍵))⌿⍵}</source>, 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.
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>~.</source>)
* [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>)


Navigation menu