8

This question is similliar to my other one

I have 2 arrays:

fruitsArray = ["apple", "mango", "blueberry", "orange"]
vegArray = ["tomato", "potato", "mango", "blueberry"]

How can I get the uncommon elements of fruitsArray comparing to vegArray

Expected Output = ["apple", orange]
Community
  • 1
  • 1
AAA
  • 1,957
  • 4
  • 23
  • 42

4 Answers4

9

Convert arrays to Set and use subtract() function to get what you want

   let fruitsArray = ["apple", "mango", "blueberry", "orange"]
   let vegArray = ["tomato", "potato", "mango", "blueberry"]

   let set1 = Set(fruitsArray)
   let set2 = Set(vegArray)

   let filter = Array(set1.subtract(set2))
   println(filter) //[apple, orange]
Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
3

One line

let fruitsArray = ["apple", "mango", "blueberry", "orange"]
let vegArray = ["tomato", "potato", "mango", "blueberry"]

let answer = fruitsArray.filter{ item in !vegArray.contains(item) }

print("\(answer)") //  ["apple", "orange"] 
JeremyP
  • 84,577
  • 15
  • 123
  • 161
2

There are actually a couple of difficulties with this operation. First off, there's a difference between the two things you could be asking for: either "difference" or "subtraction". Difference would return the elements that aren't in both arrays, so for instance:

let fruitsArray = ["apple", "mango", "blueberry", "orange"]
let vegArray = ["tomato", "potato", "mango", "blueberry"]

difference(fruitsArray, vegArray) // ["apple", "orange", "tomato", "blueberry"]

That doesn't seem to be what you're asking for, but it's worth bearing in mind.

The second is a "subtraction", which would yield your expected result. There's one more thing to bear in mind about this. The obvious one-liner:

fruitsArray.filter{ !vegArray.contains($0) }
// ["apple", "orange"]

Is quadratic. No issue if performance isn't important, but it's easily avoidable, using a Set. Now, you could convert both, and use the normal Set methods, but that's unnecessary. Converting to a Set is O(n) (I think, I'm not actually sure), but you're going to have to iterate through the set from fruitsArray anyway, and convert it back to an array in the end. The only advantage of a Set is that is has an O(1) contains method - so you only need to convert the this that you're using contains on. The most efficient way, I think, is:

let vSet = Set(vegArray)
fruitsArray.filter { m in !vSet.contains(m) }
oisdk
  • 9,763
  • 4
  • 18
  • 36
0

Powerful functional one-liner:

// Swift 1.2
let differenceResult = fruitsArray.filter({!contains(vegArray, $0)})

// Swift 2.0
let differenceResult = fruitsArray.filter(!vegArray.contains)

and obviously for your other question, simply remove the !:

// Swift 1.2
let intersectionResult = fruitsArray.filter({contains(vegArray, $0)})

// Swift 2.0
let intersectionResult = fruitsArray.filter(vegArray.contains)
Michal
  • 15,429
  • 10
  • 73
  • 104