"http://example.org/site/1/...">

How can I index duplicate elements in an array?

Starting with the following array (hashes):

[ {:name=>"site a", :url=>"http://example.org/site/1/"}, {:name=>"site b", :url=>"http://example.org/site/2/"}, {:name=>"site c", :url=>"http://example.org/site/3/"}, {:name=>"site d", :url=>"http://example.org/site/1/"}, {:name=>"site e", :url=>"http://example.org/site/2/"}, {:name=>"site f", :url=>"http://example.org/site/6/"}, {:name=>"site g", :url=>"http://example.org/site/1/"} ] 

How to add an index of duplicate URLs, for example:

 [ {:name=>"site a", :url=>"http://example.org/site/1/", :index => 1}, {:name=>"site b", :url=>"http://example.org/site/2/", :index => 1}, {:name=>"site c", :url=>"http://example.org/site/3/", :index => 1}, {:name=>"site d", :url=>"http://example.org/site/1/", :index => 2}, {:name=>"site e", :url=>"http://example.org/site/2/", :index => 2}, {:name=>"site f", :url=>"http://example.org/site/6/", :index => 1}, {:name=>"site g", :url=>"http://example.org/site/1/", :index => 3} ] 
+6
source share
3 answers

I would use a hash to track indexes. Scanning previous records over and over again seems ineffective.

 counts = Hash.new(0) array.each { | hash | hash[:index] = counts[hash[:url]] = counts[hash[:url]] + 1 } 

or a little cleaner

 array.each_with_object(Hash.new(0)) { | hash, counts | hash[:index] = counts[hash[:url]] = counts[hash[:url]] + 1 } 
+5
source
 array = [ {:name=>"site a", :url=>"http://example.org/site/1/"}, {:name=>"site b", :url=>"http://example.org/site/2/"}, {:name=>"site c", :url=>"http://example.org/site/3/"}, {:name=>"site d", :url=>"http://example.org/site/1/"}, {:name=>"site e", :url=>"http://example.org/site/2/"}, {:name=>"site f", :url=>"http://example.org/site/6/"}, {:name=>"site g", :url=>"http://example.org/site/1/"} ] array.inject([]) { |ar, it| count_so_far = ar.count{|i| i[:url] == it[:url]} it[:index] = count_so_far+1 ar << it } #=> [ {:name=>"site a", :url=>"http://example.org/site/1/", :index=>1}, {:name=>"site b", :url=>"http://example.org/site/2/", :index=>1}, {:name=>"site c", :url=>"http://example.org/site/3/", :index=>1}, {:name=>"site d", :url=>"http://example.org/site/1/", :index=>2}, {:name=>"site e", :url=>"http://example.org/site/2/", :index=>2}, {:name=>"site f", :url=>"http://example.org/site/6/", :index=>1}, {:name=>"site g", :url=>"http://example.org/site/1/", :index=>3} ] 
+3
source

If I wanted this to be effective, I would write:

 items_with_index = items.inject([[], {}]) do |(output, counts), h| new_count = (counts[h[:url]] || 0) + 1 [output << h.merge(:index => new_count), counts.update(h[:url] => new_count)] end[0] 
0
source

Source: https://habr.com/ru/post/898363/


All Articles