Categories
Tech

Scala Saturday – The partition Method

The filter function takes a collection and a predicate and returns only the items in a collection that meet the predicate. It discards the ones that don’t.

Well, what if you want to retain all the items in the collection, but you just want them separated into two groups–the sheep from goats, as it were? That’s where partition comes in. The partition operation takes a collection and a predicate, just as filter does, but instead of tossing the items that don’t meet the predicate, partition returns a second collection along with the first: one containing all the items that meet the predicate and one containing all the rest.

Maybe you run a business, and once per quarter, you want to send a message to all your customers. You send a thank you note to the customers that have made a purchase in the last quarter. To the customers who have not, you send a we-miss-you note, perhaps containing a coupon. So then, you need to partition your customer list:

A list of customers, each with a lastPurchase field that is the date of the customer's last purchase, partitioned into two lists. The first list is all customers who have made a purchase in the last three months while the other list contains customers who have not made a purchase in the last three months.
Partitioning a List of Customers Based on the Date of the Latest Purchase

Here is the Customer case class (which uses Java 8’s new LocalDate class):

case class Customer(
  name: String,
  email: String,
  latestPurchase: LocalDate)

Now given a list of customers, here is how you partition that list into those who have made recent purchases and those who have not:

val customers = List(
  Customer("Bob", "bob@bob.com", LocalDate.of(2015, Month.JUNE, 5)),
  Customer("Barb", "barb@barbara.com", LocalDate.of(2015, Month.MAY, 15)),
  Customer("Chuck", "chuck@charles.com", LocalDate.of(2015, Month.JANUARY, 26)),
  Customer("Charlie", "charlie@charlotte.com", LocalDate.of(2015, Month.MARCH, 1)),
  Customer("Dan", "dan@dan.com", LocalDate.of(2014, Month.DECEMBER, 21)),
  Customer("Deb", "deb@deborah.com", LocalDate.of(2015, Month.JANUARY, 24)),
  Customer("Ed", "ed@theodore.com", LocalDate.of(2015, Month.MARCH, 15)),
  Customer("Elle", "elle@elle.com", LocalDate.of(2015, Month.JUNE, 15))
)

val threeMosAgo = LocalDate.now.minusMonths(3)
val (recent, distant) = customers.partition {
  c => c.latestPurchase.isAfter(threeMosAgo)
}
// recent: List[Customer] = List(
//   Customer(Bob,bob@bob.com,2015-06-05),
//   Customer(Barb,barb@barbara.com,2015-05-15), 
//   Customer(Elle,elle@elle.com,2015-06-15))
// distant: List[Customer] = List(
//   Customer(Chuck,chuck@charles.com,2015-01-26),
//   Customer(Charlie,charlie@charlotte.com,2015-03-01),
//   Customer(Dan,dan@dan.com,2014-12-21),
//   Customer(Deb,deb@deborah.com,2015-01-24),
//   Customer(Ed,ed@theodore.com,2015-03-15))

Now you can send that thank you note to each of the customers in the recent list and a miss-you note to each customer in the distant list.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.