Add a block argument with Array#uniq_bang
authorJun Hiroe <[email protected]>
Fri, 18 Apr 2014 12:57:11 +0000 (18 21:57 +0900)
committerJun Hiroe <[email protected]>
Fri, 18 Apr 2014 14:13:02 +0000 (18 23:13 +0900)
mrbgems/mruby-array-ext/mrblib/array.rb
mrbgems/mruby-array-ext/test/array.rb

index 7f48811..0da5d05 100644 (file)
@@ -1,7 +1,8 @@
 class Array
   ##
   # call-seq:
-  #    ary.uniq! -> ary or nil
+  #    ary.uniq!                -> ary or nil
+  #    ary.uniq! { |item| ... } -> ary or nil
   #
   # Removes duplicate elements from +self+.
   # Returns <code>nil</code> if no changes are made (that is, no
@@ -11,13 +12,27 @@ class Array
   #    a.uniq!   #=> ["a", "b", "c"]
   #    b = [ "a", "b", "c" ]
   #    b.uniq!   #=> nil
+  #    c = [["student","sam"], ["student","george"], ["teacher","matz"]]
+  #    c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
   #
-  def uniq!
+  def uniq!(&block)
     ary = self.dup
     result = []
-    while ary.size > 0
-      result << ary.shift
-      ary.delete(result.last)
+    if block
+      hash = {}
+      while ary.size > 0
+        val = ary.shift
+        key = block.call(val)
+        hash[key] = val unless hash.has_key?(key)
+      end
+      hash.each_value do |value|
+        result << value
+      end
+    else
+      while ary.size > 0
+        result << ary.shift
+        ary.delete(result.last)
+      end
     end
     if result.size == self.size
       nil
index 9a0f25f..3be17f1 100644 (file)
@@ -36,6 +36,12 @@ assert("Array#uniq!") do
 
   b = [ "a", "b", "c" ]
   assert_nil b.uniq!
+
+  c = [["student","sam"], ["student","george"], ["teacher","matz"]]
+  assert_equal [["student", "sam"], ["teacher", "matz"]], c.uniq! { |s| s.first }
+
+  d = [["student","sam"], ["teacher","matz"]]
+  assert_nil d.uniq! { |s| s.first }
 end
 
 assert("Array#uniq") do