From: prijutme4ty@... Date: 2016-05-12T16:07:11+00:00 Subject: [ruby-core:75475] [Ruby trunk Feature#11090] Enumerable#each_uniq and #each_uniq_by Issue #11090 has been updated by Ilya Vorontsov. Assignee set to Nobuyoshi Nakada Why introduce one more method if we can just implement `#uniq` (with or without block, sticking to `Array#uniq` semantics) for `Enumerable` and `Enumerator::Lazy`? With `Enumerator::Lazy` we do not need to create an array. ```ruby module Enumerable def uniq result = [] uniq_map = {} if block_given? each do |value| key = yield value next if uniq_map.has_key?(key) uniq_map[key] = true result << value end else each do |value| next if uniq_map.has_key?(value) uniq_map[value] = true result << value end end result end end class Enumerator::Lazy def uniq uniq_map = {} if block_given? Enumerator::Lazy.new(self) do |yielder, value| key = yield value next if uniq_map.has_key?(key) uniq_map[key] = true yielder << value end else Enumerator::Lazy.new(self) do |yielder, value| next if uniq_map.has_key?(value) uniq_map[value] = true yielder << value end end end end olimpics = {1896 => 'Athens', 1900 => 'Paris', 1904 => 'Chikago', 1906 => 'Athens', 1908 => 'Rome'} each_city_first_time = olimpics.uniq{|k,v| v } # [[1896, "Athens"], [1900, "Paris"], [1904, "Chikago"], [1908, "Rome"]] (1..Float::INFINITY).lazy.uniq{|x| (x**2) % 10 }.first(6) # => [1, 2, 3, 4, 5, 10] ``` While I propose another solution for the problem, I'm totally agree that we need a way to work with unique elements of collections without creating intermediate array. In heavy data processing it is a very common problem. ---------------------------------------- Feature #11090: Enumerable#each_uniq and #each_uniq_by https://bugs.ruby-lang.org/issues/11090#change-58596 * Author: Hans Mackowiak * Status: Open * Priority: Normal * Assignee: Nobuyoshi Nakada ---------------------------------------- currently if you want to iterate the first uniq elements you either need to call `uniq` and create a big array or you need to count the elements yourself if you have an `Enumerable` with an indifferent size (maybe something with `cycle` or something you cant `rewind`) calling the `Array#uniq` method might not what you want. the idea is adding `each_uniq` which does only iterate though the elements which are not already send (it does count for you) a second `each_uniq_by` does work similar with chunk and does takes a block using a generated `Enumerator` IceDragon200 did make the following gist/sample in ruby, it might be written in C later to make it faster/better. https://gist.github.com/IceDragon200/5b1c205b4b38665c308e for better view i also added it as attachment. ---Files-------------------------------- each_uniq.rb (830 Bytes) -- https://bugs.ruby-lang.org/ Unsubscribe: