Reputation: 1
I am a beginner in Ruby. Can anyone help me to write code for this, please?
Given an Array, return the elements that are present exactly once in the array.
For example, it should pass the following test cases:
[1,4,5]
, given [1,2,2,3,3,4,5]
[1,3]
, given [1,2,2,3,4,4]
Upvotes: 0
Views: 354
Reputation: 118289
a = [1,2,2,3,3,4,5]
p a.select{|i| a.count(i) == 1}
# >> [1, 4, 5]
a = [1,2,2,3,4,4]
p a.select{|i| a.count(i) == 1}
# >> [1, 3]
Benchmarks
require 'benchmark'
a = [1,2,2,3,3,4,5]
n = 1000000
Benchmark.bm(15) do |x|
x.report('priti') { n.times { a.select{|i| a.count(i) == 1} } }
x.report('Jason') { n.times { a.group_by { |x| x }.reject { |k,v| v.count > 1 }.keys } }
x.report('rogerdpack2') { n.times {
bad = {}
good = {}
a.each{|v|
if bad.key? v
# do nothing
else
if good.key? v
bad[v] = true
good.delete(v)
else
good[v] = true;
end
end
}
good.keys
}
}
end
with this result
priti 3.152000 0.000000 3.152000 ( 3.247000)
Jason 4.633000 0.000000 4.633000 ( 4.845000)
rogerdpack2 3.853000 0.000000 3.853000 ( 3.886000)
and with a larger array:
require 'benchmark'
a = [1,2,2,3,3,4,5]*5 + [33,34]
n = 1000000
Benchmark.bm(15) do |x|
x.report('priti') { n.times { a.select{|i| a.count(i) == 1} } }
x.report('Jason') { n.times { a.group_by { |x| x }.reject { |k,v| v.count > 1 }.keys } }
x.report('rogerdpack2') { n.times {
bad = {}
good = {}
a.each{|v|
if bad.key? v
# do nothing
else
if good.key? v
bad[v] = true
good.delete(v)
else
good[v] = true;
end
end
}
good.keys
}
}
x.report('priti2') { n.times { a.uniq.select{|i| a.count(i) == 1} }}
end
you get result:
user system total real
priti 60.435000 0.000000 60.435000 ( 60.769151)
Jason 10.827000 0.016000 10.843000 ( 10.978195)
rogerdpack2 9.141000 0.000000 9.141000 ( 9.213843)
priti2 15.897000 0.000000 15.897000 ( 16.007201)
Upvotes: 4
Reputation: 66851
Here's another option:
a = [1,2,2,3,3,4,5]
b = {}
a.each{|v|
b[v] ||= 0
b[v] += 1
}
b.select{|k, v| v == 1}.keys
and here's a potentially faster one (though more complex) that is hard coded to look for items "just listed once":
a = [1,2,2,3,3,4,5]
bad = {}
good = {}
a.each{|v|
if bad.key? v
# do nothing
else
if good.key? v
bad[v] = true
good.delete(v)
else
good[v] = true;
end
end
}
good.keys
Upvotes: 0
Reputation: 3806
Put the items in an array. a = [1,2,2,3,4,4]
Then run a few filters to get the items you want.
a.group_by { |x| x }.reject { |k,v| v.count > 1 }.keys
#=> [1,3]
Updated With Stefan's keys
suggestion.
Upvotes: 5