Partitioning collections

Partitioning a collection creates a new java.util.Map of key/value pairs from values in a simple list. Gosu provides the partition and partitionUniquely methods to partition collections. Each method has a single parameter that is a Gosu block, which takes an element from the original list as the block argument. The value returned by the block becomes the key for that element in the new map. Gosu uses type inference to statically type the Map objects that the methods return.

The partition method

For example, suppose you have the following list of String values.

var myStrings = new ArrayList<String>(){"a", "b", "bb", "ab", "abc", "abcd"}

The following line of code partitions the preceding list into a Map that uses the lengths of the various String values as the keys to those value.

var lengthsToStringsMap = myStrings.partition( \ str:String -> str.length)

Because some of the values in the original list have the same lengths, the created map contains four keys and six values, which the following example map definition illustrates:

Map { 1 -> ["a", "b"], 2 -> ["bb", "ab"], 3 -> ["abc"], 4 -> ["abcd"] }

If you partition a list with the partition method, subsequent code must handle the case where a map expression resolves to a list instead of a single value.

The partitionUniquely method

If you are certain that the list contains unique values. use the partitionUniquely method. For example, suppose you have a list with the following String values. each with a different length than the others.

var myStrings = new ArrayList<String>(){"bb", "a", "abcd", "abc"}

The following line of code partitions the preceding list into a Map that uses the lengths of the various String values as the keys to those value.

var lengthsToStringsMap = myStrings.partitionUniquely( \ str:String -> str.length)

Because each value in the original list has a different length, the created map contains four keys and four values, which the following example map definition illustrates:

Map { 1 -> "a", 2 -> "bb", 3 -> "abc", 4 -> "abcd" }

If more than one list element has the same calculated value for its key, the partitionUniquely method throws an exception.

Example of partitioning a collection

The following example illustrates a typical case of partitioning a collection.

uses gw.api.database.Query
uses gw.api.database.DBFunction

// Query for new contacts from yesterday.
var contactQuery = Query.make(Contact).withLogSQL(true)
var contactResult =
        contactQuery.compare(DBFunction.DateFromTimestamp(contactQuery.getColumnRef("CreateTime")),
        Equals, java.util.Date.Yesterday ).select()

// Partition the result into a map by contact public ID.
var contactsById = contactResult.partitionUniquely( \ contact -> contact.PublicID )

The value of contactsById is a Map of contact PublicID values to contacts created yesterday. You can access a contact entity instance and its properties from the map by using the public ID as the key.