我有这个对象数组,我希望它们按照特定的键分组,在这种情况下tags
var items = [
{id: 0, tags: ["a"], name: "foo"},
{id: 1, tags: [], name: "bar"},
{id: 2, tags: ["a"], name: "bazz"},
{id: 3, tags: ["b"], name: "wah"},
{id: 4, tags: ["c"], name: "ikr"},
{id: 5, tags: ["a"], name: "wtf"},
{id: 6, tags: ["a","b"], name: "gtg"},
{id: 7, tags: ["c"], name: "afk"}
]
所以我使用了下划线,就像这样:
var groupItems = _.groupBy(items, function(obj) {
return obj.tags;
});
问题在于:
{
"a": [
{"id": 0,"tags": ["a"],"name": "foo"},
{"id": 2,"tags": ["a"],"name": "bazz"},
{"id": 5,"tags": ["a"],"name": "wtf"}
],
"": [
{"id": 1,"tags": [],"name": "bar"}
],
"b": [
{"id": 3,"tags": ["b"],"name": "wah"}
],
"c": [
{"id": 4,"tags": ["c"],"name": "ikr"},
{"id": 7,"tags": ["c"],"name": "afk"}
],
"a,b": [
{"id": 6,"tags": ["a","b"],"name": "gtg"}
]
}
如果您还注意到,那些拥有多个标签的人会从数组joined
创建一个tags
密钥,这是一个非常不理想的结果。我怎样才能按tags
对它们进行分组,并在数据有多个tags
答案 0 :(得分:1)
假设当某个项目包含多个标记时,您希望每个标记下都有重复的条目_.groupBy
将无法执行您想要的操作,因为它只是简单地拆分了一个集合(赢得了重复的条目)。
相反,您需要手动循环您的商品,然后是每个商品的标签,并为您建立清单(如果需要,可以使用_.each
):
var items = [
{id: 0, tags: ["a"], name: "foo"},
{id: 1, tags: [], name: "bar"},
{id: 2, tags: ["a"], name: "bazz"},
{id: 3, tags: ["b"], name: "wah"},
{id: 4, tags: ["c"], name: "ikr"},
{id: 5, tags: ["a"], name: "wtf"},
{id: 6, tags: ["a","b"], name: "gtg"},
{id: 7, tags: ["c"], name: "afk"}
];
var groupItems = {};
for (var i = 0, item; item = items[i]; i++) {
for (var t = 0, tag; tag = item.tags[t]; t++) {
// If we do not have an array for our tag, add one
groupItems[tag] = groupItems[tag] || [];
// Push out item onto the tag's list in our groupItems
groupItems[tag].push(item);
}
}
哪个会给你:
{
"a": [
{"id": 0,"tags": ["a"],"name": "foo"},
{"id": 2,"tags": ["a"],"name": "bazz"},
{"id": 5,"tags": ["a"],"name": "wtf"},
{"id": 6,"tags": ["a","b"],"name": "gtg"}
],
"b": [
{"id": 3,"tags": ["b"],"name": "wah"},
{"id": 6,"tags": ["a","b"],"name": "gtg"}
],
"c": [
{"id": 4,"tags": ["c"],"name": "ikr"},
{"id": 7,"tags": ["c"],"name": "afk"}
]
}
答案 1 :(得分:1)
我根据您的需求创建了一个解决方案,重视可读性和维护
var items = [
{id: 0, tags: ["a"], name: "foo"},
{id: 1, tags: [], name: "bar"},
{id: 2, tags: ["a"], name: "bazz"},
{id: 3, tags: ["b"], name: "wah"},
{id: 4, tags: ["c"], name: "ikr"},
{id: 5, tags: ["a"], name: "wtf"},
{id: 6, tags: ["a"], name: "gtg"},
{id: 7, tags: ["c"], name: "afk"}
]
function groupByTags(items){
var grouped = {};
items.forEach(function(item){
var tags = item.tags;
if(!tags.length) tags.push("");
tags.forEach(function(tag){
if(tag in grouped == false){
grouped[tag] = [];
}
grouped[tag].push(item);
});
});
return grouped;
}
console.log(groupByTags(items));
答案 2 :(得分:1)
这是一个正确处理空标记数组的小函数。您可能希望将forEach
替换为for
循环以获得更好的性能,并添加一些类型检查以使此功能更通用且更不容易出错。
function groupBy(arr, propName) {
var grouped = {};
arr.forEach(function (thing) {
var values = thing[propName];
if (!values.length) {
grouped[''] = grouped[''] || [];
grouped[''].push(thing);
return;
}
values.forEach(function (value) {
grouped[value] = grouped[value] || [];
grouped[value].push(thing)
});
});
return grouped;
}
答案 3 :(得分:0)
items.reduce(function(acc, el) {
(el.tags.length === 0 ? [""] : el.tags).forEach(function(el2) {
if (!acc[el2]) acc[el2] = [];
acc[el2].push(el);
});
return acc;
}, {});
var items = [{
id: 0,
tags: ["a"],
name: "foo"
}, {
id: 1,
tags: [],
name: "bar"
}, {
id: 2,
tags: ["a"],
name: "bazz"
}, {
id: 3,
tags: ["b"],
name: "wah"
}, {
id: 4,
tags: ["c"],
name: "ikr"
}, {
id: 5,
tags: ["a"],
name: "wtf"
}, {
id: 6,
tags: ["a", "b"],
name: "gtg"
}, {
id: 7,
tags: ["c"],
name: "afk"
}]
var result = items.reduce(function(acc, el) {
(el.tags.length === 0 ? [""] : el.tags).forEach(function(el2) {
if (!acc[el2]) acc[el2] = [];
acc[el2].push(el);
});
return acc;
}, {});
document.getElementById('res').innerHTML = JSON.stringify(result, null, 2)
<pre id="res"></pre>