Skip to content

Instantly share code, notes, and snippets.

@NicolasT
Forked from anonymous/gist:4327307
Created December 18, 2012 11:42
Show Gist options
  • Save NicolasT/4327314 to your computer and use it in GitHub Desktop.
Save NicolasT/4327314 to your computer and use it in GitHub Desktop.
import itertools
# Utilities
# Using curried form
# Split an iterable at a point where some given predicate is met
split_at = lambda f: lambda l: \
(itertools.takewhile(lambda e: not f(e), l), itertools.dropwhile(lambda e: not f(e), l))
# Append an element to a list
append = lambda l: lambda e: l + [e]
# Map a pair of functions over a pair of values, pairwise (heh)
map_pair = lambda ((f, g)): lambda ((a, b)): (f(a), g(b))
# Uncurry. To turn a curried function into an uncurried one
uncurry = lambda f: lambda ((a, b)): f(a)(b)
# The actual function
# Ideally the 'list' application should be 'id (lambda v: v)', but somehow that
# drops a single element from every range except for the first or the last, not
# sure why :-/
group_ranges = lambda ranges: lambda values: \
uncurry(append)(
reduce(
lambda (acc, vs), d: map_pair((append(acc), list))(split_at(lambda e: e >= d)(vs)),
ranges,
([], sorted(values))))
# Demo
test_data = range(0, 15)
test_ranges = [2, 5, 9]
# Think ranges = [(0, 2), (2, 5), (5, 9)]
print map(list, group_ranges(test_ranges)(test_data))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment