Reputation: 1242
I have an Array of Arrays that contains numbers in a particular order. I want to remove the duplicates out of the nested arrays, but there is a hierarchy: If a number occurs in a lower-index of the array, remove all duplicates down the Array chain.
Example: nums = [[10, 6, 14], [6], [10, 6, 9], [10, 13, 6], [10, 13, 6, 9, 16], [10, 13]]
nums[0] contains [10,6,14] so any subsequent mention of 10,6,14 should be removed from the other arrays in the chain, meaning nums[2] should have 10,6 removed and only 9 should remain.
I'm having trouble doing this with nested loops, can any Ruby wizards help please?
Upvotes: 3
Views: 1698
Reputation: 67910
Yet another way. It keeps original order of elements in arrays:
require 'set'
nums = [[10, 6, 14], [6], [10, 6, 9], [10, 13, 6], [10, 13, 6, 9, 16], [10, 13]]
nums2 = nums.inject([[], Set.new]) do |(output, seen), ary|
[output << ary.reject { |a| seen.include?(a) }, seen.union(ary)]
end[0]
p nums2
# [[10, 6, 14], [], [9], [13], [16], []]
Upvotes: 1
Reputation: 303549
Is the following incorrect? Should the [6]
be removed or not?
nums = [[10, 6, 14], [6], [10, 6, 9], [10, 13, 6], [10, 13, 6, 9, 16], [10, 13]]
def remove_duplicate_numbers( array )
seen = []
array.map{ |sub_array|
result = sub_array - seen
seen += sub_array
result
}
end
p remove_duplicate_numbers( nums )
#=> [[10, 6, 14], [], [9], [13], [16], []]
If this is not what you want, please post the actual output you expect for your array.
Upvotes: 0
Reputation: 196
require 'set'
nums = [[10, 6, 14], [6], [10, 6, 9], [10, 13, 6], [10, 13, 6, 9, 16], [10, 13]]
found = Set.new
new_nums = []
for subarray in nums do
sub_new = []
for i in subarray do
if not found.member? i
sub_new << i
end
found << i
end
new_nums << sub_new
end
puts(nums.inspect)
puts(new_nums.inspect)
Upvotes: 3
Reputation: 132972
This should do it:
input = [[10, 6, 14], [6], [10, 6, 9], [10, 13, 6], [10, 13, 6, 9, 16], [10, 13]]
seen = []
output = input.map do |numbers|
new = numbers.uniq - seen
seen += new
new
end
# => output is [[10, 6, 14], [], [9], [13], [16], []]
If you want to remove the empty lists in the output, simply
output.reject!(&:empty?)
Upvotes: 10