Home > Software design >  Optimal way to transfer values from a Map<K, V<List>> to a Map<otherKey, otherValue&l
Optimal way to transfer values from a Map<K, V<List>> to a Map<otherKey, otherValue&l

Time:11-30

Heres what i got to work with: Map<Faction, List<Resource>>

  • Faction is the enum String value of a player faction (e.g "rr" for team red, "bb" for team blue)
  • Resources is String enum value of a Resource e.g "Wool", "Lumber"

So the list looks like this right now:

("rr", "wool")
("rr", "wool")
("rr", "lumber")
("bb", "wool")

So my goal is to have a Map<Resource, Integer>

  • where Resource is String name of a Resource from an enum
  • Integer represents the amount of Resource Cards

Example of target contained values: ("Wool", 4), ("Grain", 3), ("Lumber", 2)


So I'm trying to do this (in pseudocode):

  • extract all resources belonging to Faction "rr" and put them into a map <Resources, Integer> where each resource type should be represented once and Integer represents the sum of the amount of Resource cards --> repeat this step for 3 more player Faction

I've played around with streams and foreach loops but have produced no valuable code yet because I struggle yet in the conception phase.

CodePudding user response:

It seems that actual input data in Map<Faction, List<Resource>> look like:

{rr=[wool, wool, lumber], bb=[lumber, wool, grain]}

Assuming that appropriate enums are used for Resource and Faction, the map of resources to their amount can be retrieved using flatMap for the values in the input map:

Map<Faction, List<Resource>> input; // some input data

Map<Resource, Integer> result = input
    .values() // Collection<List<Resource>>
    .stream() // Stream<List<Resource>>
    .flatMap(List::stream) // Stream<Resource>
    .collect(Collectors.groupingBy(
        resource -> resource,
        LinkedHashMap::new, // optional map supplier to keep insertion order
        Collectors.summingInt(resource -> 1)
    ));

or Collectors.toMap may be applied:

...
    .collect(Collectors.toMap(
        resource -> resource,
        resource -> 1,
        Integer::sum,      // merge function to summarize amounts
        LinkedHashMap::new // optional map supplier to keep insertion order
    ));
  • Related