The other answers will work, but groupBy is an expensive operation and inefficient if you have 10k employees and the first two have the same name.
1) Short method: (distinct internally builds a HashSet of all the values)
val names = employees.map(_.name)
names.distinct != names
2) Efficient method: (only traverses as much of the seq as it needs to before finding dupe)
def hasDupes(employees: Seq[Employee]): Boolean = {
val names = collection.mutable.Set.empty[String]
employees.foreach { e =>
if (names(e.name)) return true
names += e.name
}
false
}
You can write this as a one-liner using a tail-recursive method, but the fact is that immutable sets are much slower than mutable ones so not much good if we're going for efficiency.
3) Off-the-wall method: (doesn't build a set at all, but starts a quicksort and quits (via a cheap exception) as soon as it finds two names the same. Should be efficient. )
class Dupe extends Throwable with util.control.NoStackTrace
val dupeOrd = new Ordering[Employee] {
def compare(x: Employee, y: Employee) =
if (x.name == y.name) throw new Dupe else x.name compare y.name
}
def hasDupes(employees: Seq[Employee]) =
try { employees.sorted(dupeOrd); false } catch { case e: Dupe => true }
Benchmark of results, with method 0 being om-nom-nom's groupBy one, (time in ms for 1000 runs on 1000 employee Vector, no duplicates):
method time Early return if duplicate found
0 (groupBy) 1560 No
1 (distinct) 329 No
2a (mutable.Set) 255 Yes
2b (immutable.Set) 1414 Yes
3 (sorting) 666 Yes //242 if employees already in name order