0

I have a function that expects two arguments from type Set:

def union[A](set1: Set[A], set2: Set[A]): Set[A] = {
  set1.foldLeft(set2){ (set, elt) => (set + elt) }
}

Apply function as follow:

union(Set(3,4,5,6), Set(34,56,23))

and I've got:

res2: Set[Int] = Set(5, 56, 6, 34, 3, 23, 4)

but I expect:

Set(3,4,5,6,34,56,23)

Why do I receive such as unordered result?

softshipper
  • 32,463
  • 51
  • 192
  • 400

2 Answers2

4

Set is an unordered data type, generally the order is determined by the implementation and is generally not guaranteed (much less guaranteed to be insertion ordered).

to get the behaviour you seem to want (distinct, insertion ordered) I would suggest using Lists and the distinct method

(List(3,4,5,6) ++ List(34,56,23)).distinct
res0: List[Int] = List(3, 4, 5, 6, 34, 56, 23)
Angelo Genovese
  • 3,398
  • 17
  • 23
  • I don't recommend doing as this just builds a set under the hood needlessly. See my answer for a better suggestion. – Crembo Apr 10 '17 at 18:37
  • @Crembo your answer ends up using an ordering, the question asks for insertion order so while your answer is slightly more efficient it doesn't actually answer the question asked. – Angelo Genovese Apr 12 '17 at 14:28
1

Sets do not preserve an order - if you would like what you expect as your end result you can try this, note that it returns an ArrayBuffer (which you can then convert to what you need):

union(Set(3,4,5,6), Set(34,56,23)).toSeq.sorted

As we are dealing with a simple Ordering (Int), we don't need to specify the conditions for it to be ordered as it's implicitly done. Since your union def takes in any type, an Ordering will need to be specified based on the type you passed in. See this on guidance on creating an Ordering.

Community
  • 1
  • 1
Tanjin
  • 2,442
  • 1
  • 13
  • 20