Hoe een objectveld te selecteren voor de kaartwaarde in Groovy met behulp van groupby

Ik heb een lijst met mensen met persoonsobjecten met de methoden getName() en getYearOfBirth (). Ik gebruik groupBy om de Person-objecten te groeperen. Ik gebruik groupBy om de Person-objecten te groeperen, maar ik wil alleen de namen op de kaart zetten, omdat Person in de toekomst nog veel extra velden zal hebben. De jaren zullen de sleutels zijn.

    class Person {
        String name
        int yearOfBirth
    }       

    def people = [ 
        new Person(name:"Tom", yearOfBirth:1985),
        new Person(name:"Abigail", yearOfBirth:1987),
        new Person(name:"Joyce", yearOfBirth:1984),
        new Person(name:"James", yearOfBirth:1987),
        new Person(name:"Scott", yearOfBirth:1985),
        new Person(name:"Ruth", yearOfBirth:1984)
    ]           

    //people.groupBy(_.year) mapValues (_ map (_.name))  how to map here?

This is a direct port of a Scala app

2

2 antwoord

Een oplossing zou zijn:

def nameInYear = people.groupBy { it.yearOfBirth }
                       .collectEntries { [ (it.key):it.value.name ] }
assert nameInYear[ 1984 ] == [ 'Joyce', 'Ruth' ]

So, group them by their year of birth to get a YEAR->ListOfPeople map Then, for each of these groupings, collect a map of YEAR->ListOfNames

2
toegevoegd

Een andere, meer dwingende, oplossing zou zijn:

def namesByYear = [:].withDefault { [] } 
people.each { namesByYear[it.yearOfBirth] << it.name }

assert namesByYear[1985] == ['Tom', 'Scott']

Hetzelfde kan worden omgezet in één uitdrukking met behulp van inject , hoewel ik denk dat het minder leesbaar wordt:

def namesByYear = people.inject([:].withDefault { [] }) { map, p ->
    map[p.yearOfBirth] << p.name
    map
}
0
toegevoegd