使用Underscore.js,我想组项目列表多次,即
集团通过大小,然后为每个大小,按类别分组...
http://jsfiddle.net/rickysullivan/WTtXP/1/
理想情况下,我想有一个函数或延长_.groupBy()
这样就可以在它与PARAMATERS通过抛出一个阵列组。
var multiGroup = ['size', 'category'];
也许可以只让一个mixin ...
_.mixin({
groupByMulti: function(obj, val, arr) {
var result = {};
var iterator = typeof val == 'function' ? val : function(obj) {
return obj[val];
};
_.each(arr, function(arrvalue, arrIndex) {
_.each(obj, function(value, objIndex) {
var key = iterator(value, objIndex);
var arrresults = obj[objIndex][arrvalue];
if (_.has(value, arrvalue))
(result[arrIndex] || (result[arrIndex] = [])).push(value);
我的头好痛,但我觉得有些更推动需求何去何从?
});
})
return result;
}
});
properties = _.groupByMulti(properties, function(item) {
var testVal = item["size"];
if (parseFloat(testVal)) {
testVal = parseFloat(item["size"])
}
return testVal
}, multiGroup);
Answer 1:
一个简单的递归实现:
_.mixin({
/*
* @mixin
*
* Splits a collection into sets, grouped by the result of running each value
* through iteratee. If iteratee is a string instead of a function, groups by
* the property named by iteratee on each of the values.
*
* @param {array|object} list - The collection to iterate over.
* @param {(string|function)[]} values - The iteratees to transform keys.
* @param {object=} context - The values are bound to the context object.
*
* @returns {Object} - Returns the composed aggregate object.
*/
groupByMulti: function(list, values, context) {
if (!values.length) {
return list;
}
var byFirst = _.groupBy(list, values[0], context),
rest = values.slice(1);
for (var prop in byFirst) {
byFirst[prop] = _.groupByMulti(byFirst[prop], rest, context);
}
return byFirst;
}
});
演示中您的jsfiddle
Answer 2:
我觉得@ BERGI的回答可以利用罗Dash的精简一点mapValues
(超过对象值映射函数)。 它使我们能够在组由以嵌套的方式多个键的阵列中的条目:
_ = require('lodash');
var _.nest = function (collection, keys) {
if (!keys.length) {
return collection;
}
else {
return _(collection).groupBy(keys[0]).mapValues(function(values) {
return nest(values, keys.slice(1));
}).value();
}
};
我改名的方法来nest
,因为它结束了服务倍受D3的服务的同一角色窝运营商。 见这个要点的详细信息和这个小提琴与您的示例演示使用。
lodash 巢 GROUPBY
Answer 3:
这个怎么样,而简单的黑客?
console.log(_.groupBy(getProperties(), function(record){
return (record.size+record.category);
}));
Answer 4:
看看这个下划线扩展: Underscore.Nest ,艾琳罗斯。
这个扩展的输出将是从您指定的内容略有不同,但模块大约只有100行代码,所以你应该能够扫描得到的方向。
Answer 5:
这是一个伟大的使用案例的减少相的map-reduce。 它不会是为多组功能在视觉上优雅(你不能在键的阵列组上刚及格),但总体来说这种模式给你更多的灵活性,以转换数据。 例
var grouped = _.reduce(
properties,
function(buckets, property) {
// Find the correct bucket for the property
var bucket = _.findWhere(buckets, {size: property.size, category: property.category});
// Create a new bucket if needed.
if (!bucket) {
bucket = {
size: property.size,
category: property.category,
items: []
};
buckets.push(bucket);
}
// Add the property to the correct bucket
bucket.items.push(property);
return buckets;
},
[] // The starting buckets
);
console.log(grouped)
但如果你只是想在一个下划线混入,这是我的刺吧:
_.mixin({
'groupAndSort': function (items, sortList) {
var grouped = _.reduce(
items,
function (buckets, item) {
var searchCriteria = {};
_.each(sortList, function (searchProperty) { searchCriteria[searchProperty] = item[searchProperty]; });
var bucket = _.findWhere(buckets, searchCriteria);
if (!bucket) {
bucket = {};
_.each(sortList, function (property) { bucket[property] = item[property]; });
bucket._items = [];
buckets.push(bucket);
}
bucket._items.push(item);
return buckets;
},
[] // Initial buckets
);
grouped.sort(function (x, y) {
for (var i in sortList) {
var property = sortList[i];
if (x[property] != y[property])
return x[property] > y[property] ? 1 : -1;
}
return 0;
});
return _.map(grouped, function (group) {
var toReturn = { key: {}, value: group.__items };
_.each(sortList, function (searchProperty) { toReturn.key[searchProperty] = group[searchProperty]; });
return toReturn;
});
});
Answer 6:
在BERGI的方法的改进通过joyrexus不采取下划线/ lodash混入系统的优势。 这是一个mixin:
_.mixin({
nest: function (collection, keys) {
if (!keys.length) {
return collection;
} else {
return _(collection).groupBy(keys[0]).mapValues(function(values) {
return _.nest(values, keys.slice(1));
}).value();
}
}
});
Answer 7:
与lodash和混入的示例
_.mixin({
'groupByMulti': function (collection, keys) {
if (!keys.length) {
return collection;
} else {
return _.mapValues(_.groupBy(collection,_.first(keys)),function(values) {
return _.groupByMulti(values, _.rest(keys));
});
}
}
});
Answer 8:
下面是一个很容易理解的功能。
function mixin(list, properties){
function grouper(i, list){
if(i < properties.length){
var group = _.groupBy(list, function(item){
var value = item[properties[i]];
delete item[properties[i]];
return value;
});
_.keys(group).forEach(function(key){
group[key] = grouper(i+1, group[key]);
});
return group;
}else{
return list;
}
}
return grouper(0, list);
}
Answer 9:
由复合材料关键组倾向于在大多数情况下更好地为我工作:
const groups = _.groupByComposite(myList, ['size', 'category']);
演示使用OP的小提琴
Mixin
_.mixin({
/*
* @groupByComposite
*
* Groups an array of objects by multiple properties. Uses _.groupBy under the covers,
* to group by a composite key, generated from the list of provided keys.
*
* @param {Object[]} collection - the array of objects.
* @param {string[]} keys - one or more property names to group by.
* @param {string} [delimiter=-] - a delimiter used in the creation of the composite key.
*
* @returns {Object} - the composed aggregate object.
*/
groupByComposite: (collection, keys, delimiter = '-') =>
_.groupBy(collection, (item) => {
const compositeKey = [];
_.each(keys, key => compositeKey.push(item[key]));
return compositeKey.join(delimiter);
}),
});
文章来源: Underscore.js groupBy multiple values