Skip to content

Instantly share code, notes, and snippets.

@Tomalak
Created January 3, 2015 23:44
Show Gist options
  • Save Tomalak/84e80ded100b600ab40e to your computer and use it in GitHub Desktop.
Save Tomalak/84e80ded100b600ab40e to your computer and use it in GitHub Desktop.
linq.js Dynamic Multilevel Grouping
/* Utility functions to create a nested, multilevel grouped, ordered
* structure out of a flat array of uniform objects.
*
* usage: result = applyStructure(items, structure);
*
* structure is an object of the form:
* {
* group: "propertyName1"
* order: ["propertyName1", "propertyName2 DESC", ...]
* next: {
* group: "propertyName3"
* order: ["propertyName3 DESC"]
* next: {
* // etc
* }
* }
* }
*
* also see http://jsfiddle.net/Tomalak/xth6ayuo/
*/
// Enumerable, definition => Enumerable
function applyOrder(items, definition) {
var i, prop, prefix, suffix, orderFunc;
if (!items) return;
if (!definition) return items;
for (i = 0; i < definition.length; i++) {
// definition[i] is either "propertyName" or "propertyName DESC"
prop = (definition[i] + " ").split(" ");
prefix = i === 0 ? "OrderBy" : "ThenBy";
suffix = prop[1].toUpperCase() === "DESC" ? "Descending" : "";
orderFunc = prefix + suffix;
items = items[orderFunc]("$." + prop[0]);
}
return items;
}
// Enumerable, definition => Enumerable
function applyGroup(items, definition) {
if (!items) return;
if (!definition) return items;
items = applyOrder(items, definition.order);
if (!definition.group) return items;
return items.GroupBy("$." + definition.group, "", function (key, e) {
return {
group: definition.group,
key: key,
items: applyGroup(e, definition.then).ToArray()
};
});
}
// Array, definition => Array
function applyStructure(items, definition) {
if (!items) return;
if (!definition) return items;
return applyGroup(Enumerable.From(items), definition).ToArray();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment