-1

I'm having troubles with 2D arrays to get the values that exist in one array and don't exist in another one.

We have 2 arrays

[["001", 1, 3333, "maja", "eka", 17, "110B"], ["005", 1, 1434, "buve", "eka", 27, "110A"], ["008", 1, 1111, "maja", "", 31, "110"]]

And the second one

[["001", 1, 3333, "maja", "eka", 17, "110B"], ["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]

So the output should be the

[["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]

Atm I'm doing it in this way, but I struggle because it returns only 1 record

detect = []
records = first_array.collect {|a| a[0]} - second_array.collect {|a| a[0]}
    records.each do |r|
      detect = first_array.detect { |k, v| k == r }
    end
return detect
Viktor
  • 323
  • 4
  • 15
  • 1
    Your question is unclear. `['005', 1, 1434, 'buve', 'eka, '27', '110A']` is an example value that exists in first table but does not in other. Should it be in result table? – Marek Lipka Sep 23 '19 at 08:01
  • Possible duplicate of [Subtracting one Array from another in Ruby](https://stackoverflow.com/questions/1192186/subtracting-one-array-from-another-in-ruby) – Viktor Sep 23 '19 at 09:38
  • @Виктор Not really. can't agree with you.I've forgotten that the in these 2 arrays are not the same(amount of values in array and the values of them), except the first value(index)(I've fixed the post). So now things are more complicated. – Viktor Sep 23 '19 at 09:44
  • 1
    That's a horrible way to do things. You posted a question, went afk, got 6 answers and then came back to change the question completely? You have to value other people's time and effort in helping you. The best thing you can do is accept an answer that answers your original question and then make a new question better worded and more clearly. Make sure to include proper examples (not just one) next time. – Viktor Sep 23 '19 at 09:49
  • @Виктор Without blamelessly, please. If I were unable to answer at once, then I was away from my PC. – Viktor Sep 23 '19 at 09:51

6 Answers6

3

You can use the - operator

a = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["005", 1, 1434, "buve", "eka", 27, "110A"], ["008", 1, 1111, "maja", "", 31, "110"]]
b = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]

# You can find the difference between the arrays with - operator
a - b 
#~> [["005", 1, 1434, "buve", "eka", 27, "110A"], ["008", 1, 1111, "maja", "", 31, "110"]]
b - a 
#~> [["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]
Viktor
  • 2,623
  • 3
  • 19
  • 28
demir
  • 4,591
  • 2
  • 22
  • 30
0

to get the values that exist in one array and don't exist in another one

To get this result, you don't have to write your own solution, all you need is:

(a1 - a2) + (a2 - a1)
Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
0
a = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["005", 1, 1434, "buve", "eka", 27, "110A"], ["008", 1, 1111, "maja", "", 31, "110"]]
b = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]

if you use a[0] - b[0] it will give array that has a's values but not b's. if you use b[0] - a[0] it will give array that has b's values but not a's. to get unique values from both array you use should do ((a[0] - b[0]) - (a[0] - b[0])).uniq

a.each_with_index.map{|arr, index| ((arr - b[index]) + (b[index] - arr)).uniq }.reject!(&:empty?)

(supposing both array are of same size)

Touqeer
  • 583
  • 1
  • 4
  • 19
0

Simplest Example

a1 = [[1,2,3],[1,2]] 
a2 = [[1,2,3],[1,3]]
a1-a2
[[1, 2]] 
a2-a1
[[1, 3]] 
Saif chaudhry
  • 409
  • 3
  • 10
0

To get the difference between the subarrays you'll need to iterate. I believe this offers the best solution for brevity and performance, as others deal with flat arrays, leave unneeded elements or iterate multiple times.

Here's how:

If you're using Ruby 2.7:

a = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["005", 1, 1434, "buve", "eka", 27, "110A"], ["008", 1, 1111, "maja", "", 31, "110"]]
b = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]

a.map.with_index { |arr, i| b[i].difference(arr) }
# => [[], ["007", 3381, 31, "110"], ["009", 2824, 28, "110C"]]

Or before 2.7:

a.map.with_index { |arr, i| b[i] - arr }
# => [[], ["007", 3381, 31, "110"], ["009", 2824, 28, "110C"]]

If you need to avoid having the empty arrays appearing where results are identical, you can tweak a bit:

# Ruby 2.7
a.filter_map.with_index do |arr, i|
  diff = b[i].difference(arr)
  diff if diff.any?
end
# => [["007", 3381, 31, "110"], ["009", 2824, 28, "110C"]]

# < Ruby 2.7
a.each_with_object([]).with_index do |(arr, results), i|
  diff = b[i] - arr
  results << diff if diff.any?
end
# => [["007", 3381, 31, "110"], ["009", 2824, 28, "110C"]]

Hope that helps - let me know how you get on or if you have any questions.

SRack
  • 11,495
  • 5
  • 47
  • 60
0

The desired solution is as:

    irb> a = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["005", 1, 1434, "buve", "eka", 27, "110A"], ["008", 1, 1111, "maja", "", 31, "110"]]
    irb> b = [["001", 1, 3333, "maja", "eka", 17, "110B"], ["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]]
    irb> b-a
         => [["007", 1, 3381, "buve", "eka", 31, "110"], ["009", 1, 2824, "maja", "", 28, "110C"]] 
vidur punj
  • 5,019
  • 4
  • 46
  • 65