# \[Feature:1.9\] {Array,Enumerable}#uniq\_by, #uniq\_by!

**URL:** <https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260>\
**Category:** Development\
**Created:** [February 13, 2009, 2:22pm UTC](https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260 "2009-02-13T14:22:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [February 13, 2009, 2:22pm UTC](https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260/1 "2009-02-13T14:22:08Z")

</div>

e$B$J$+$@$G$9!#e(B

e$B%V%m%C%/$NCM$K$7$?$,$C$F0l0U$N$b$N$rA\*$V!"e(BArray#uniq\_bye$B$H$$$&$Ne(B  
e$B$O$I$&$G$7$g$&$+!#e(B

# Index: array.c

— array.c (revision 22100)  
+++ array.c (working copy)  
@@ -2875,13 +2875,40 @@ ary\_add\_hash(VALUE hash, VALUE ary)  
}

## -static VALUE -ary\_make\_hash(VALUE ary) +static inline VALUE +ary\_tmp\_hash\_new(void) { VALUE hash = rb\_hash\_new();

```
 RBASIC(hash)->klass = 0;

```

- return hash;  
+}
- 

+static VALUE  
+ary\_make\_hash(VALUE ary)  
+{

- VALUE hash = ary\_tmp\_hash\_new();  
return ary\_add\_hash(hash, ary);  
}

+static VALUE  
+ary\_add\_hash\_by(VALUE hash, VALUE ary)  
+{

- long i;
- 
- for (i = 0; i \< RARRAY\_LEN(ary); ++i) {
- VALUE v = rb\_ary\_elt(ary, i), k = rb\_yield(v);
- if (rb\_hash\_lookup2(hash, k, Qundef) == Qundef) {
- 

```
 rb_hash_aset(hash, k, v);

```

- }
- }
- return hash;  
+}
- 

+static VALUE  
+ary\_make\_hash\_by(VALUE ary)  
+{

- VALUE hash = ary\_tmp\_hash\_new();
- return ary\_add\_hash\_by(hash, ary);  
+}
- 

static inline void  
ary\_recycle\_hash(VALUE hash)  
@@ -3063,4 +3090,43 @@ rb\_ary\_uniq(VALUE ary)  
}

+static int  
+push\_value(st\_data\_t key, st\_data\_t val, st\_data\_t ary)  
+{

- rb\_ary\_push((VALUE)ary, (VALUE)val);
- return ST\_DELETE;  
+}
- 

+static VALUE  
+rb\_ary\_uniq\_by\_bang(VALUE ary)  
+{

- VALUE hash;
- long size;
- 
- RETURN\_ENUMERATOR(ary, 0, 0);
- hash = ary\_make\_hash\_by(ary);
- size = RHASH\_SIZE(hash);
- if (RARRAY\_LEN(ary) == size) return Qnil;
- ary\_resize\_capa(ary, size);
- ARY\_SET\_LEN(ary, 0);
- st\_foreach(RHASH\_TBL(hash), push\_value, ary);
- ary\_recycle\_hash(hash);
- return ary;  
+}
- 

+static VALUE  
+rb\_ary\_uniq\_by(VALUE ary)  
+{

- VALUE hash;
- long size;
- 
- RETURN\_ENUMERATOR(ary, 0, 0);
- hash = ary\_make\_hash\_by(ary);
- size = RHASH\_SIZE(hash);
- ary = ary\_new(rb\_obj\_class(ary), size);
- st\_foreach(RHASH\_TBL(hash), push\_value, ary);
- ary\_recycle\_hash(hash);
- return ary;  
+}
- 

/\*

- call-seq:  
@@ -3920,4 +3986,6 @@ Init\_Array(void)  
rb\_define\_method(rb\_cArray, “uniq”, rb\_ary\_uniq, 0);  
rb\_define\_method(rb\_cArray, “uniq!”, rb\_ary\_uniq\_bang, 0);

- rb\_define\_method(rb\_cArray, “uniq\_by”, rb\_ary\_uniq\_by, 0);
- rb\_define\_method(rb\_cArray, “uniq\_by!”, rb\_ary\_uniq\_by\_bang, 0);  
rb\_define\_method(rb\_cArray, “compact”, rb\_ary\_compact, 0);  
rb\_define\_method(rb\_cArray, “compact!”, rb\_ary\_compact\_bang, 0);  
Index: enum.c  
===================================================================  
— enum.c (revision 22100)  
+++ enum.c (working copy)  
@@ -1794,4 +1794,29 @@ enum\_cycle(int argc, VALUE \*argv, VALUE  
}

+static VALUE  
+enum\_uniq\_by\_i(VALUE i, VALUE hash, int argc, VALUE \*argv)  
+{

- return rb\_hash\_aset(hash, rb\_yield\_values(argc, argv), i);  
+}
- 

+static int  
+push\_value(st\_data\_t key, st\_data\_t val, st\_data\_t ary)  
+{

- rb\_ary\_push((VALUE)ary, (VALUE)val);
- return ST\_DELETE;  
+}
- 

+static VALUE  
+enum\_uniq\_by(VALUE obj)  
+{

- VALUE hash = rb\_hash\_new(), uniq;
- 
- RBASIC(hash)-\>klass = 0;
- rb\_block\_call(obj, id\_each, 0, 0, enum\_uniq\_by\_i, hash);
- uniq = rb\_ary\_new2(RHASH\_SIZE(hash));
- st\_foreach(RHASH\_TBL(hash), push\_value, uniq);
- return uniq;  
+}
- 

/\*

- The `Enumerable` mixin provides collection classes with  
@@ -1853,4 +1878,5 @@ Init\_Enumerable(void)  
rb\_define\_method(rb\_mEnumerable, “drop\_while”, enum\_drop\_while, 0);  
rb\_define\_method(rb\_mEnumerable, “cycle”, enum\_cycle, -1);

- rb\_define\_method(rb\_mEnumerable, “uniq\_by”, enum\_uniq\_by, 0);

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [February 14, 2009, 10:22am UTC](https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260/2 "2009-02-14T10:22:33Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:37998] [Feature:1.9]  
{Array,Enumerable}#uniq\_by, #uniq\_by!”  
on Fri, 13 Feb 2009 22:19:41 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|e$B%V%m%C%/$NCM$K$7$?$,$C$F0l0U$N$b$N$rA\*$V!"e(BArray#uniq\_bye$B$H$$$&$Ne(B  
|e$B$O$I$&$G$7$g$&$+!#e(B

e$B8=:\_%V%m%C%/$r\<u$1IU$1$F$$$J$$$N$G$9$+$i!“e(Buniq\_bye$B$r?75,$KF3F~e(B  
e$B$9$k$h$j$be(B uniq{|x| f(x}  
e$B$G!V%V%m%C%/$NCM$K=\>$C$F0l0U$N$b$N$re(B  
e$BA\*$V!WJ}$,NI$$$N$G$O$J$$$G$7$g$&$+!#e(Bsort, maxe$B$H$O0[$J$j$^$9e(B  
e$B$,!”$3$l$i$O85$+$i%V%m%C%/$r\<h$C$F$$$^$7$?$+$i!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [February 14, 2009, 4:47pm UTC](https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260/3 "2009-02-14T16:47:38Z")

</div>

e$B%A%1%C%He(B #1154 e$B$,99?7$5$l$^$7$?!#e(B (by Nobuyoshi N.)

e$B%9%F!\<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B  
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

## Applied in changeset r22307.

[http://redmine.ruby-lang.org/issues/show/1154](http://redmine.ruby-lang.org/issues/show/1154)

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [February 16, 2009, 9:29am UTC](https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260/4 "2009-02-16T09:29:08Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:38015] Re: [Feature:1.9]  
{Array,Enumerable}#uniq\_by, #uniq\_by!”  
on Sun, 15 Feb 2009 06:59:09 +0900, Kazuhiro NISHIYAMA  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|uniq\_bye$B$NJ}$,%V%m%C%/$J$7$N;~$Ke(BEnumeratore$B$,F@$i$l$FJXMx$+$be(B  
|e$B$7$l$J$$$H;W$C$?$N$G$9$,!"$I$&$G$7$g$&$+e(B?

e$B%V%m%C%/$J$7$Ge(BEnumeratore$B$r$b$i$C$F$&$l$7$$\>l9g$,;W$$$D$-$^$;e(B  
e$B$s!#$`$7$m!"%V%m%C%/$rEO$7$Fe(B(e$BG[Ns$G$O$J$/e(B)Enumeratore$B$G$[$7$$e(B  
e$B$H$$$&$J$i$o$+$j$^$9$,!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [February 14, 2009, 11:01pm UTC](https://www.ruby-forum.com/t/feature-1-9-array-enumerable-uniq-by-uniq-by/160260/5 "2009-02-14T23:01:26Z")

</div>

e$B@\>;3OB9-$G$9!#e(B

At Sat, 14 Feb 2009 18:19:59 +0900,  
Yukihiro M. wrote:

> |e$B%V%m%C%/$NCM$K$7$?$,$C$F0l0U$N$b$N$rA\*$V!"e(BArray#uniq\_bye$B$H$$$&$Ne(B  
> |e$B$O$I$&$G$7$g$&$+!#e(B
> 
> e$B8=:\_%V%m%C%/$r\<u$1IU$1$F$$$J$$$N$G$9$+$i!“e(Buniq\_bye$B$r?75,$KF3F~e(B  
> e$B$9$k$h$j$be(B uniq{|x| f(x} e$B$G!V%V%m%C%/$NCM$K=\>$C$F0l0U$N$b$N$re(B  
> e$BA\*$V!WJ}$,NI$$$N$G$O$J$$$G$7$g$&$+!#e(Bsort, maxe$B$H$O0[$J$j$^$9e(B  
> e$B$,!”$3$l$i$O85$+$i%V%m%C%/$r\<h$C$F$$$^$7$?$+$i!#e(B

uniq\_bye$B$NJ}$,%V%m%C%/$J$7$N;~$Ke(BEnumeratore$B$,F@$i$l$FJXMx$+$be(B  
e$B$7$l$J$$$H;W$C$?$N$G$9$,!"$I$&$G$7$g$&$+e(B?
