Excluding current element in iteration

Suppose I have something like this:

val vector = Vector(a, b, c, d) 

for (element <- vector if element.minSeparation(vector))
doSomething

The minSeparation method compares the currently selected element with each element in the rest of the vector. The problem is that I don’t want to compare it to itself. So what is the best way to create a copy of the vector without the current element? Note that some elements could possibly be identical, and I don’t want to eliminate copies of the current element, just the current element itself. Thanks.

2 Likes

I would use a function similar to tails or permutations, that iterates through every element and the corresponding vector with that element excluded. I don’t think it’s part of the std library but it’s not that hard to write.

scala> def iterate[A](v: Vector[A]): Iterator[(A, Vector[A])] = 
     |   Iterator.unfold(0){ i =>
     |     v.unapply(i).map{ a =>
     |       (a, v.patch(i, Nil, 1)) -> (i + 1)
     |     }
     |   }
def iterate[A](v: Vector[A]): Iterator[(A, Vector[A])]

scala> iterate(Vector.empty[Int]).toList
val res30: List[(Int, Vector[Int])] = List()

scala> iterate(Vector(1)).toList
val res31: List[(Int, Vector[Int])] = List((1,Vector()))

scala> iterate(Vector(1,2)).toList
val res32: List[(Int, Vector[Int])] = List((1,Vector(2)), (2,Vector(1)))

scala> iterate(Vector(1,2,3,4)).toList
val res33: List[(Int, Vector[Int])] = List((1,Vector(2, 3, 4)), (2,Vector(1, 3, 4)), (3,Vector(1, 2, 4)), (4,Vector(1, 2, 3)))

So you could use that like this:

for ((element, diff) <- iterate(vector) if element.minSeparation(diff)) {
  doSomething
}
1 Like

Given that this is a Vector, you might also be able to iterate over the indices and use splitAt, tail, and concat to achieve this behavior.

Nice. Thanks.