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:
Here is the Customer
type:
type Customer(name : string, email : string, latestPurchase : DateTime) = member x.Name = name member x.Email = email member x.LatestPurchase = latestPurchase override x.ToString() = latestPurchase.ToString("dd MMM yyyy") |> sprintf "Customer(%s, %s, %s)" name email
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:
let customers = [ Customer("Bob", "bob@bob.com", DateTime.Parse "5 Jun 2015") Customer("Barb", "barb@barbara.com", DateTime.Parse "15 May 2015") Customer("Chuck", "chuck@charles.com", DateTime.Parse "26 Jan 2015") Customer("Charlie", "charlie@charlotte.com", DateTime.Parse "1 Mar 2015") Customer("Dan", "dan@dan.com", DateTime.Parse "21 Dec 2014") Customer("Deb", "deb@deborah.com", DateTime.Parse "24 Jan 2015") Customer("Ed", "ed@theodore.com", DateTime.Parse "15 Mar 2015") Customer("Elle", "elle@elle.com", DateTime.Parse "15 Jun 2015") ] let threeMosAgo = DateTime.Now.AddMonths -3 let recent, distant = customers |> List.partition (fun c -> c.LatestPurchase > threeMosAgo) // val recent : Customer list = // [Customer(Bob, bob@bob.com, 05 Jun 2015); // Customer(Barb, barb@barbara.com, 15 May 2015); // Customer(Elle, elle@elle.com, 15 Jun 2015)] // val distant : Customer list = // [Customer(Chuck, chuck@charles.com, 26 Jan 2015); // Customer(Charlie, charlie@charlotte.com, 01 Mar 2015); // Customer(Dan, dan@dan.com, 21 Dec 2014); // Customer(Deb, deb@deborah.com, 24 Jan 2015); // Customer(Ed, ed@theodore.com, 15 Mar 2015)]
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.
One reply on “F# Friday – The partition Function”
[…] F# Friday – The partition Function – Brad Collins […]