3

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?

0

4 Answers 4

10

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?)
Sign up to request clarification or add additional context in comments.

2 Comments

Wow, that is beautiful and elegant. Thanks!
Accepted as answer now, site made me wait 2 minutes.
3
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)

Comments

1

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], []]

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.