documentcloud/underscore — pull request #904 by sstephenson (2012-12-15 22:35:09+00:00)
Title: Add _.collateBy for collating ordered collections by a given criterion

This patch adds an `_.collateBy` method, similar to `_.groupBy` but designed for collating ordered collections by a given criterion.

Collation is useful when you want to display a collection in a particular order while grouping similar items together under a common heading or in a shared section.

#### Example: Grouping a conversation by author

```javascript
var messages = [
{author: "Bob", body: "Hello"},
{author: "Bob", body: "Are you there?"},
{author: "Jane", body: "I'm here."},
{author: "Jane", body: "How can I help you?"},
{author: "Bob", body: "Nevermind."}
];
```

```jst

<% _.each(_.collateBy(messages, 'author'), function(group) { %>

<%= group[0] %>

<% _.each(group[1], function(message) { %>

<%= message.body %>

<% }); %>

<% }); %>

```

```html

Bob

Hello

Are you there?

Jane

I'm here.

How can I help you?

Bob

Nevermind.

````

#### Example: Displaying an event timeline

```javascript
var events = [
{date: "2012-12-14", project: "New Product", author: "Scott", description: "commented on: Status update"},
{date: "2012-12-14", project: "Operations", author: "Trevor", description: "commented on: Unexpected downtime"},
{date: "2012-12-14", project: "Operations", author: "John", description: "commented on: Unexpected downtime"},
{date: "2012-12-14", project: "New Product", author: "Ryan", description: "posted a message: Status update"},
{date: "2012-12-14", project: "Redesign", author: "Ryan", description: "added a to-do: Tighten margins"},
{date: "2012-12-13", project: "Redesign", author: "Jason", description: "completed a to-do: Explore alternate layout"},
{date: "2012-12-13", project: "Operations", author: "John", description: "posted a message: Unexpected downtime"},
{date: "2012-12-13", project: "Operations", author: "Taylor", description: "completed a to-do: Monthly firedrill"},
{date: "2012-12-13", project: "New Product", author: "Ryan", description: "commented on: Checklist for launch"}
];
```

```jst

<% _.each(_.collateBy(events, 'date'), function(eventsByDate) { %>

<%= eventsByDate[0] %>

<% _.each(_.collateBy(eventsByDate[1], 'project'), function(eventsByProject) { %>

<%= eventsByProject[0] %>

<% _.each(eventsByProject[1], function(event) { %>

<%= event.author %>
<%= event.description %>

<% }); %>

<% }); %>

<% }); %>

```

```html

2012-12-14

New Product

Scott
commented on: Status update

Operations

Trevor
commented on: Unexpected downtime

John
commented on: Unexpected downtime

New Product

Ryan
posted a message: Status update

Redesign

Ryan
added a to-do: Tighten margins

2012-12-13

Redesign

Jason
completed a to-do: Explore alternate layout

Operations

John
posted a message: Unexpected downtime

Taylor
completed a to-do: Monthly firedrill

New Product

Ryan
commented on: Checklist for launch

```