Skip to content

Instantly share code, notes, and snippets.

@Willmo36
Last active October 20, 2017 10:57
Show Gist options
  • Save Willmo36/85e35a964a1b52fa6e57891704c1dcea to your computer and use it in GitHub Desktop.
Save Willmo36/85e35a964a1b52fa6e57891704c1dcea to your computer and use it in GitHub Desktop.
Split T[] into T[][].
function toRanges<T>(items: T[], comparator: (a: T, b: T) => boolean): T[][] {
return items.reduce<T[][]>(
(acc, item) => {
const previousItem = R.last(R.last(acc));
if (R.isNil(previousItem)) {
acc[acc.length - 1].push(item);
return acc;
}
const isNewRange = comparator(item, previousItem);
if (isNewRange) {
acc.push([item]);
} else {
acc[acc.length - 1].push(item);
}
return acc;
},
[[]]
);
}
//recursive version
export const x = <T>(comparator: RangeComparator<T>, ranges: T[][] = []) => (items: T[]): T[][] => {
//base case
if (R.isEmpty(items)) {
return ranges;
}
//inductive step
const [item, ...rest] = items;
if (R.isEmpty(ranges)) {
ranges.push([item]);
return x(comparator, ranges)(rest);
}
//with previous item, compare
const currentRange = R.last(ranges);
const previousItem = R.last(currentRange);
const isNewRange = comparator(previousItem, item);
if (isNewRange) {
ranges.push([item]);
} else {
ranges[ranges.length - 1].push(item);
}
return x(comparator, ranges)(rest);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment