Multidimensional array, remove the similar values

#1

Hi All,

I am new to Ruby and now having an issue.
i.e.
I have 4 arrays:
a = [1,2,3,4]
b = [2,3,4,5]
c = [3,4,5,6]
d = [4,5,6,7]
and want to receive the following result:
[ [1, 2, 3, 4] [5] [6] [7] ]
Basically want to remove the duplicate values but keep the arrays.
I have tried the followings:
[a|b|c|d] but it gave [[1, 2, 3, 4, 5, 6, 7]]
a|b|c|d it gave [1, 2, 3, 4, 5, 6, 7]

Thank you in advance for your help.

#2

One way to do it
e =[a, ["#{b[3"]}, ["#{c[3]}], ["#{d[3]}"] ]

1 Like
#3
l =[[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7]]
cum=[]
p l.map {|sl|
  diff=sl-cum
  cum = cum+diff
  diff
}
> ruby  cum.rb
[[1, 2, 3, 4], [5], [6], [7]]
#4

@r.aubarede’s solution won’t work, if you e.g. have

a = [1,1,1,1]
b = ...

and want those 1s to be removed (keeping only one)

However, this do work:

require "set"

seen = Set.new

arr.map do |subarr| 
  subarr.map do |elem| 
    if seen.include?(elem) 
      nil
    else 
      seen << elem
      elem
    end
  end.compact
end
1 Like
#5

Thank you for your help @madsohm

#6

I also get the following:

newarray = [a, b-a, c-b-a, d-c-b-a]
Obviously If I had 100+ arrays it would not be so efficient.

#7

Do you want this? :bulb:

#!/usr/bin/ruby -w

a, b, c, d = [1,2,3,4], [2,3,4,5], [3,4,5,6], [4,5,6,7], [10, 8, 7, 8]
ba, oth, bb = [b, c, d], a.dup, [a.dup]

ba.each { |i| i.-(oth).tap { |v| bb.push(v) }.each { |i| oth.push(i) } }
p bb

Output :candy:

[[1, 2, 3, 4], [5], [6], [7]]


Or the Efficient Way :star2:

a = Array.new(10, &:itself)
ba = [Array.new(15, &:next), Array.new(20, &:next) ]

oth, bb = a.dup, [a.dup]
ba.each { |i| bb.push(i.-(oth).tap { |v| oth.concat(v) }) }
p bb

This code is similar, but you see, it has more arrays. On the other hand, pushing each element is way more expensive (slower, resource hogging) than concating all the elements altogether. The output will be :candy:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]


With 100 Arrays? :100:

a = [1,2,3,4]
ba = 100.times.map { rand(2..10).times.map { rand(1..0xfffffffff) } }
oth, bb = a.dup, [a.dup]

ba.each { |i| bb.push(i.-(oth).tap { |v| oth.concat(v) }) }
p bb

Output :candy:

Well, you know it will mess up everything here!


I apologise for the variable names. I don’t have sweet names for them :crying_cat_face:

Hope this answers your question! :sparkles:

1 Like