Skip to content

Instantly share code, notes, and snippets.

@mmun
Last active December 31, 2015 11:39
Show Gist options
  • Save mmun/7980583 to your computer and use it in GitHub Desktop.
Save mmun/7980583 to your computer and use it in GitHub Desktop.
Computed groupBy
(function() {
var get = Ember.get, set = Ember.set;
function findItemInsertionIndex(group, changeMeta, instanceMeta) {
for (var i = get(group, 'length') - 1; i >= 0; i--) {
var currentItem = group.objectAt(i),
currentIndex = instanceMeta.itemGuidToIndex[Ember.guidFor(currentItem)];
if (currentIndex < changeMeta.index) {
return i + 1;
}
}
return 0;
}
function getGroup(groups, item, propertyKey) {
var value = get(item, propertyKey);
var group = groups.findBy('value', value);
if (!group) {
group = Ember.A();
set(group, 'value', value);
groups.pushObject(group);
}
return group;
}
function removeItem(groups, group, item) {
group.removeObject(item);
if (Ember.isEmpty(group)) {
groups.removeObject(group);
}
}
Ember.computed.groupBy = function(dependentKey, propertyKey) {
return Ember.reduceComputed(dependentKey + ".@each." + propertyKey, {
initialize: function (groups, changeMeta, instanceMeta) {
instanceMeta.itemGuidToIndex = Ember.Object.create();
return groups;
},
initialValue: function() {
return Ember.A();
},
addedItem: function(groups, item, changeMeta, instanceMeta) {
instanceMeta.itemGuidToIndex[Ember.guidFor(item)] = changeMeta.index;
var group = getGroup(groups, item, propertyKey);
var insertionIndex = findItemInsertionIndex(group, changeMeta, instanceMeta);
group.insertAt(insertionIndex, item);
return groups;
},
removedItem: function(groups, item, changeMeta, instanceMeta) {
var value;
if (changeMeta.previousValues) {
value = changeMeta.previousValues[propertyKey];
} else {
delete instanceMeta.itemGuidToIndex[Ember.guidFor(item)];
value = get(item, propertyKey);
}
var group = groups.findBy('value', value);
removeItem(groups, group, item);
return groups;
}
});
};
})();
@mmun
Copy link
Author

mmun commented Dec 16, 2013

Example: http://emberjs.jsbin.com/IpeHuWi/2/edit

Takes as input an array of objects and a key. Ouputs an array of arrays grouped by value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment