Reputation: 75
Allright so i don't know if this is possible, but let's say we have the following list:
List(1, 2, 3, 1)
If i want to apply a map over this, is there a way for me to check if i've already had a value before, e.g. on the 4th value (the 2nd 1) it'll say that it already came across the 1 and then throw an error or something.
Upvotes: 3
Views: 211
Reputation: 36229
List(1, 2, 3, 1).distinct.map (n => n*n)
// res163: List[Int] = List(1, 4, 9)
This code removes duplicates, then performs the mappings in a self documenting, brief manner.
Upvotes: 2
Reputation: 51271
fold
is probably the way to go. The problem is that each iteration has to carry both the memory of previous elements as well as the map()
results as it is being built.
List(1, 2, 3, 11).foldRight((Set[Int](),List[String]())) {case (i, (st, lst)) =>
if (st(i)) throw new Error //duplicate encountered
else (st + i, i.toString :: lst) //add to memory and map result
}._2 //pull the map result from the tuple
Upvotes: 1
Reputation: 61656
This would be the role of a foldLeft
stage:
List(1, 2, 3, 1).foldLeft(List[Int]()) {
// The item has already been encountered:
case (uniqueItems, b) if uniqueItems.contains(b) => {
// If as stated, you want to throw an exception, that's where you could do it
uniqueItems
}
// New item not seen yet:
case (uniqueItems, b) => uniqueItems :+ b
}
foldLeft traverses a sequence while working (at each new element), with a result based on the previous ones.
For each element, the pattern matching (uniqueItems, b)
should be understood this way: uniqueItems
is the "accumulator" (it's initialized as List[Int]()
) and will be updated (or not) for each item of the list. And b
if the new item of the list which is currently being processed.
By the way, this example is a (non-efficient) distinct
over a list.
Upvotes: 4