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
@@ -382,4 +397,24 @@ class Array
end
ary
end
+
+ ##
+ # call-seq:
+ # ary.rotate!(count=1) -> ary
+ #
+ # Rotates +self+ in place so that the element at +count+ comes first, and
+ # returns +self+.
+ #
+ # If +count+ is negative then it rotates in the opposite direction, starting
+ # from the end of the array where +-1+ is the last element.
+ #
+ # a = [ "a", "b", "c", "d" ]
+ # a.rotate! #=> ["b", "c", "d", "a"]
+ # a #=> ["b", "c", "d", "a"]
+ # a.rotate!(2) #=> ["d", "a", "b", "c"]
+ # a.rotate!(-3) #=> ["a", "b", "c", "d"]
+
+ def rotate!(count=1)
+ self.replace(self.rotate(count))
+ end
end