Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - Find element not in common for two arrays

Tags:

I've been thinking about a following problem - there are two arrays, and I need to find elements not common for them both, for example:

a = [1,2,3,4]
b = [1,2,4]

And the expected answer is [3].

So far I've been doing it like this:

a.select { |elem| !b.include?(elem) }

But it gives me O(N ** 2) time complexity. I'm sure it can be done faster ;)

Also, I've been thinking about getting it somehow like this (using some method opposite to & which gives common elements of 2 arrays):

a !& b  #=> doesn't work of course

Another way might be to add two arrays and find the unique element with some method similar to uniq, so that:

[1,1,2,2,3,4,4].some_method #=> would return 3
like image 316
Jacka Avatar asked Nov 25 '13 22:11

Jacka


People also ask

How do you compare two arrays in Ruby?

Arrays can be equal if they have the same number of elements and if each element is equal to the corresponding element in the array. To compare arrays in order to find if they are equal or not, we have to use the == operator.

How do you find the element of two arrays?

Write a JavaScript function to find the unique elements from two arrays. ES6 Version: function difference(arr1,arr2) { const a1= flatten(arr1,true); const a2= flatten(arr2,true); const a=[]; const diff=[]; for(var i=0;i< a1. length;i++) a[a1[i]]=false; for(i=0;i< a2.

What does .first mean in Ruby?

The first() is an inbuilt method in Ruby returns an array of first X elements. If X is not mentioned, it returns the first element only. Syntax: range1.first(X) Parameters: The function accepts X which is the number of elements from the beginning. Return Value: It returns an array of first X elements.


1 Answers

The simplest (in terms of using only the arrays already in place and stock array methods, anyway) solution is the union of the differences:

a = [1,2,3,4]
b = [1,2,4]
(a-b) | (b-a)
=> [3]

This may or may not be better than O(n**2). There are other options which are likely to give better peformance (see other answers/comments).

Edit: Here's a quick-ish implementation of the sort-and-iterate approach (this assumes no array has repeated elements; otherwise it will need to be modified depending on what behavior is wanted in that case). If anyone can come up with a shorter way to do it, I'd be interested. The limiting factor is the sort used. I assume Ruby uses some sort of Quicksort, so complexity averages O(n log n) with possible worst-case of O(n**2); if the arrays are already sorted, then of course the two calls to sort can be removed and it will run in O(n).

def diff a, b
  a = a.sort
  b = b.sort
  result = []
  bi = 0
  ai = 0
  while (ai < a.size && bi < b.size)
    if a[ai] == b[bi]
      ai += 1
      bi += 1
    elsif a[ai]<b[bi]
      result << a[ai]
      ai += 1
    else
      result << b[bi]
      bi += 1
    end
  end
  result += a[ai, a.size-ai] if ai<a.size
  result += b[bi, b.size-bi] if bi<b.size
  result
end
like image 50
Reinstate Monica -- notmaynard Avatar answered Oct 15 '22 13:10

Reinstate Monica -- notmaynard