views:

222

answers:

1

why the methods transform (in-place mutation version of map) and retain (in-place mutation version of filter) are defined on only mutable.Map but not on mutable.Buffer and mutable.Set? shouldnt all mutable collections support these methods?

+8  A: 

The operations retain and transform of Map are about keys and values, concepts which are not part of a Set or a Buffer.

A Map is an Iterable consisting of pairs of keys and values (also named mappings or associations).
The fundamental operations on maps are similar to those on sets.

But your operations are listed in:

Mutable maps support in addition the operations summarized in the following table.

ms transform f

Transforms all associated values in map ms with function f.

ms retain p

Keeps only those mappings in ms that have a key satisfying predicate p.


one-zero-zero-one comments:

retain and transform are essentially in-place mutation versions of filter and map respectively and can be easily defined on Set and Buffer.
I don't see how they are Map-specific.

I would argue that retain and transform offer Map-specific implementations (in that their implementation specifically deals with keys and values) for features like the ones provided by map and filter from TraversableLike.

Implementing transform in Set and Buffer would add little value as it would simply deffer to map.


Note: Michael Kebe comments:

One more thing. immutable.MapLike has the method transform, but not the method retain.

(as opposed to mutable.MapLike which has both)

This seems however in-line with the nature of transformation operations if transform produces a new map by filtering and transforming bindings of an existing map.

Here is the source code for transform

def transform[C, That](f: (A, B) => C)(implicit bf: CanBuildFrom[This, (A, C), That]): That = {
  val b = bf(repr)
  for ((key, value) <- this) b += ((key, f(key, value)))
  b.result
}

Source code for retain, however, modified the current instance, which can only be compatible with Mutable objects:

/** Retains only those mappings for which the predicate
 *  `p` returns `true`.
 *
 * @param p  The test predicate 
 */
def retain(p: (A, B) => Boolean): this.type = {
  for ((k, v) <- this ; if !p(k, v))
    this -= k

  this
}
VonC
-1, `retain` and `transform` are essentially in-place mutation versions of `filter` and `map` respectively and can be easily defined on `Set` and `Buffer`. I don't see how they are `Map`-specific.
one-zero-zero-one
@one: the way they are documented involves Map-specific notions. But you are right, they could be extended to Set and Buffer. However, since `filter` and `map` are already there, may be this was less necessary for `Set` and `Buffer`.
VonC
@one-zero-zero-one: I have updated my answer to reflect on your comment.
VonC