From ccf7696fa70c6719c56acdfa5deab74c05e9058c Mon Sep 17 00:00:00 2001 From: Ary Borenszweig <aborenszweig@manas.com.ar> Date: Sun, 2 Nov 2014 10:05:44 -0300 Subject: [PATCH] Better Array#uniq! implementation --- src/array.cr | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/array.cr b/src/array.cr index 88171eb0eb..74eefad3fb 100644 --- a/src/array.cr +++ b/src/array.cr @@ -34,7 +34,7 @@ class Array(T) end def &(other : Array(U)) - hash = other.each_with_object(Hash(T, Bool).new) { |o, h| h[o] = true } + hash = other.to_lookup_hash ary = Array(T).new(Math.min(length, other.length)) i = 0 each do |obj| @@ -77,7 +77,7 @@ class Array(T) def -(other : Array(U)) ary = Array(T).new(length - other.length) - hash = other.each_with_object(Hash(T, Bool).new) { |o, h| h[o] = true } + hash = other.to_lookup_hash each do |obj| ary << obj unless hash.has_key?(obj) end @@ -264,7 +264,7 @@ class Array(T) end true end - + def fill each_index { |i| @buffer[i] = yield i } @@ -628,16 +628,23 @@ class Array(T) end def uniq!(&block : T -> U) - uniq_elements = Set(U).new - delete_if do |elem| - key = yield elem - if uniq_elements.includes? key - true - else - uniq_elements << key - false - end + if length <= 1 + return self + end + + hash = to_lookup_hash { |elem| yield elem } + if length == hash.length + return self + end + + @length = hash.length + + ptr = @buffer + hash.each do |k, v| + ptr.value = v + ptr += 1 end + self end @@ -722,4 +729,17 @@ class Array(T) end index end + + protected def to_lookup_hash + to_lookup_hash { |elem| elem } + end + + protected def to_lookup_hash(&block : T -> U) + each_with_object(Hash(U, T).new) do |o, h| + key = yield o + unless h.has_key?(key) + h[key] = o + end + end + end end -- GitLab