Skip to content

Operator: ToDictionary #96

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

Closed
benjchristensen opened this issue Jan 18, 2013 · 4 comments
Closed

Operator: ToDictionary #96

benjchristensen opened this issue Jan 18, 2013 · 4 comments

Comments

@akarnokd
Copy link
Member

I believe the equivalent to IDictionary is a Map in Java, but there are a lot of map classes (Linked, Concurrent, etc.). Which one should be the default value type? Is it okay to call the methods Observable.toMap() ?

@abersnaze
Copy link
Contributor

I vote for java.util.HashMap by default with an overload that lets you pass in a map class of any type you want.

public <K, V, M extends java.util.Map<K, V>> Observable<M> toMap(Class<M> mapClass, Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> elementSelector) {...}

PS: not sure if I got the co/contra-variance right on that.
PPS: I Think the consensus was to ignore EqualityComparators overloads because the idiomatic java way is to implement equals/hashCode on the class.

@samuelgruetter
Copy link
Contributor

Two questions:

  • How many times will this operator call onNext? Just once, or every time it gets a new item?
  • Are users allowed to modify the returned map?

@akarnokd
Copy link
Member

This is how I did it somewhere else (below):

  • Takes a factory which returns a map instance on subscription
  • emits the map once the source finishes
  • no variance on the output observable's type
public class OperationToMap {
    public static class ToMap<T, K, V> implements OnSubscribeFunc<Map<K, V>> {
        private final Observable<T> source;
        private final Func1<? super T, ? extends K> keySelector;
        private final Func1<? super T, ? extends V> valueSelector;
        private final Func0<? extends Map<K, V>> mapFactory;
        public ToMap(
                Observable<T> source,
                Func1<? super T, ? extends K> keySelector,
                Func1<? super T, ? extends V> valueSelector,
                Func0<? extends Map<K, V>> mapFactory
                ) {
            this.source = source;
            this.keySelector = keySelector;
            this.valueSelector = valueSelector;
            this.mapFactory = mapFactory;
        }
        @Override
        public Subscription onSubscribe(Observer<? super Map<K, V>> t1) {
            return source.subscribe(new ToMapObserver(t1));
        }
        public class ToMapObserver implements Observer<T> {
            Map<K, V> map;
            private final Observer<? super Map<K, V>> t1;
            public ToMapObserver(Observer<? super Map<K, V>> t1) {
                map = mapFactory.call();
                this.t1 = t1;
            }
            @Override
            public void onCompleted() {
                Map<K, V> map0 = map;
                map = null;
                t1.onNext(map0);
                t1.onCompleted();
            }
            @Override
            public void onError(Throwable e) {
                map = null;
                t1.onError(e);
            }
            @Override
            public void onNext(T args) {
                K key = keySelector.call(args);
                V value = valueSelector.call(args);
                map.put(key, value);
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants