-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor toMap #67
Refactor toMap #67
Conversation
I like the idea, but please give me some time to check/think about the details ;-) Moreover, I'd like to know if anything of this PR is a breaking change. It would be nice to have a comparison of what {works/doesn't work} {with/without} this PR. Could then also be copied to the release notes of the first version containg these changes. |
} | ||
|
||
def toTreeMap[K](keySelector: T => K)(implicit ord: Ordering[K]): Observable[scala.collection.immutable.TreeMap[K, T]] = { | ||
toMap[K, T, scala.collection.immutable.TreeMap](keySelector, v => v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scala.collection.immutable.TreeMap
---> immutable.TreeMap
I updated the description and override the PR with a formal commit. Sorry that I should have done it at first. |
You're right. Thanks for pointing out it. I created a helper method def to[K, V, M[_, _]](keySelector: T => K, valueSelector: T => V)(implicit cbf: CanBuildFrom[Nothing, (K, V), M[K, V]]): Observable[M[K, V]] = { and used to implement |
Btw did you try out if you can implement
|
It won't work. Here is the signature of def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, T, Col[T @uncheckedVariance]]): Observable[Col[T @uncheckedVariance]] It expects a
|
I see. def toMap[T, U](implicit ev: A <:< (T, U)): Map[T, U] |
val m = o.toMap(keySelector, valueSelector, mapFactory) | ||
println(m.toBlocking.single) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you remove this example, you should show how we can do this now. Not necessarily with a non-empty starting map, but maybe with a HashMap from the collection library?
Done
Done
Added two examples to show how to use
Maybe it's better not to add |
Yes, I think so. |
val o : Observable[String] = List("alice", "bob", "carol").toObservable | ||
val keySelector = (s: String) => s.head | ||
val valueSelector = (s: String) => s.tail | ||
val m = o.to[Char, String, HashMap](keySelector, valueSelector) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite like these two examples because none of them shows explicitly what's happening. I'd only make one example, but add all types there:
val m: Observable[HashMap[Char, String]] = o.to[Char, String, HashMap](keySelector, valueSelector)
IMHO that's more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And while I'm reading this, I wonder why we don't swap the order of the type params:
o.to[HashMap, Char, String](keySelector, valueSelector)
corresponds better to the order of pronouncing what we're doing: we say "convert o to a HashMap of Char/String".
We should not forget to make |
Sounds great. Done. |
I cannot figure out how to refactor def to[M[_, _], Col[_], K, V](keySelector: T => K, valueSelector: T => V)
(implicit mcbf: CanBuildFrom[Nothing, (K, Col[V]), M[K, Col[V]]],
cbf: CanBuildFrom[Nothing, V, Col[V]]): Observable[M[K, Col[V]]] = {
lift {
(subscriber: Subscriber[M[K, Col[V]]]) => {
new Subscriber[T](subscriber) {
val b = mcbf()
override def onStart(): Unit = request(Long.MaxValue)
override def onNext(t: T): Unit = {
val key = keySelector(t)
val value = valueSelector(t)
// how to add value to b?
// b expects (K, Col[V])
}
override def onError(e: Throwable): Unit = {
subscriber.onError(e)
}
override def onCompleted(): Unit = {
subscriber.onNext(b.result)
subscriber.onCompleted()
}
}
}
}
}
|
We could also use |
Sent another PR #68 for |
* @return an Observable that emits a single item: an `Map` containing the mapped items from the source | ||
* Observable | ||
*/ | ||
def toMap[K, V](keySelector: T => K, valueSelector: T => V): Observable[Map[K, V]] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try if you can define a default argument of v => v
for valueSelector? Not sure if this can work because scalac would have to infer from this that T must be the same as V.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not work...
@samuelgruetter further suggestion? |
LGTM |
A PR to refactor
toMap
.There is a breaking change in this PR:
def toMap[K, V] (keySelector: T => K, valueSelector: T => V, mapFactory: () => Map[K, V]): Observable[Map[K, V]]
The other changes are still source compatible and binary compatible.