CosmicGiant
CosmicGiant

Reputation: 6441

How to get flattened list from dictionary key query where values are lists?

I am trying to create an event/messaging system where the subscribers can subscribe to general event types or specific event types.

I have a dictionary of event types containing lists of subscribers of said types, and, for notifying the events to the subscribers, I want to get a flattened list of all subscriptions within those lists, where the subscription is of a type that is equal to or assignable from the event's type; in other words, when the dictionary key meets that as a criteria.

How do I get a flattened list of the items of lists queried from a dictionary's keys (using linq)?


My WIP code:

private Dictionary<Type, List<SomeEventDelegate>> subscriptions;

// ...other code...

public void Dispatch(SomeEvent someEvent)
    {
        // This should get the Key-Value pairs... How do I get a flattened list of all items in the values (which are lists themselves)?
        List<SomeEventDelegate> subscribers =
            from subscription in subscriptions
            where subscription.Key.IsAssignableFrom(someEvent.GetType())
            select subscription;

        //After I have the flattened list, I will dispatch the event to each subscriber here, in a foreach loop.
    }

Upvotes: 0

Views: 161

Answers (2)

SelectMany should do the job:

List<SomeEventDelegate> subscribers =
    subscriptions.Where(kvp => 
        kvp.Key.IsAssignableFrom(someEvent.GetType())
    ).SelectMany(kvp => kvp.Value)
    .ToList();

You can only do it with the chained-method-call syntax. You pass it a lambda that selects an IEnumerable<T> from the parameter, and as it goes it merges all the enumerables that it collects from each item in the query into one big flat query, which it returns.

Upvotes: 2

Ivan Stoev
Ivan Stoev

Reputation: 205589

If you prefer the query syntax (hence don't bother what exact method is used), why don't you just continue your query:

   List<SomeEventDelegate> subscribers =
        (from subscription in subscriptions
         where subscription.Key.IsAssignableFrom(someEvent.GetType())
         from subscriber in subscription.Value
         select subscriber)
        .ToList();

Upvotes: 1

Related Questions