如何根据 属性 值对数组进行分组?
How do I group an array based on a property value?
我有两个 JavScript objects (POJO):
var first_original = [
{group: "A", title: "foo1"},
{group: "A", title: "foo2"},
{group: "A", title: "foo3"},
{group: "A", title: "foo4"},
{group: "B", title: "foo5"},
{group: "B", title: "foo6"},
{group: "B", title: "foo7"}
];
var second_original = [
{group: null, title: "bar1"},
{group: null, title: "bar2"},
{group: null, title: "bar3"},
{group: null, title: "bar4"},
{group: null, title: "bar5"},
{group: null, title: "bar6"},
{group: null, title: "bar7"}
];
我很难概念化如何将它们映射到以下结构:
var first_copy = [
{
header: "A",
items: [
{group: "A", title: "foo1"},
{group: "A", title: "foo2"},
{group: "A", title: "foo3"},
{group: "A", title: "foo4"}
]
},
{
header: "B",
items: [
{group: "B", title: "foo5"},
{group: "B", title: "foo6"},
{group: "B", title: "foo7"}
]
}
];
var second_copy = [
{
header: null,
items: [
{group: null, title: "bar1"},
{group: null, title: "bar2"},
{group: null, title: "bar3"},
{group: null, title: "bar4"},
{group: null, title: "bar5"},
{group: null, title: "bar6"},
{group: null, title: "bar7"}
]
}
];
我尝试使用 .forEach()
:
function getRemappedObject(contentList) {
val lastGroup = null;
var currentIndex = 0;
var groups = [];
contentList.forEach(function(item) {
if (!groups[currentIndex]) {
groups.push({items: [item]});
} else {
groups[currentIndex].items.push(item);
}
groups[currentIndex].header = item.group;
if (item.group && item.group !== lastGroup) {
lastGroup = item.group;
currentIndex++;
}
});
return groups;
}
但这在规范的 header 部分惨遭失败。我认为这是睡眠不足,但我很好奇是否有更好的方法。我想在没有 Underscore 或 Lodash 的情况下解决它。请使用 ECMAScript 5 或 6。
如何将上述结构映射到预期输出?
使用另一个 Array 来跟踪 header 值;
function organise(arr) {
var headers = [], // an Array to let us lookup indicies by group
objs = [], // the Object we want to create
i, j;
for (i = 0; i < arr.length; ++i) {
j = headers.indexOf(arr[i].group); // lookup
if (j === -1) { // this entry does not exist yet, init
j = headers.length;
headers[j] = arr[i].group;
objs[j] = {};
objs[j].header = arr[i].group;
objs[j].items = [];
}
objs[j].items.push( // create clone
{group: arr[i].group, title: arr[i].title}
);
}
return objs;
}
var first_copy = organise(first_original);
如果您可以假设分组将始终是 string 即永远不会 null
您可以通过键而不是 indexOf 查找更有效地完成它
ES6 可能会让你更像这里的其他解决方案一样通过例如a Map(WeakMap 不允许基元作为键)
我有两个 JavScript objects (POJO):
var first_original = [
{group: "A", title: "foo1"},
{group: "A", title: "foo2"},
{group: "A", title: "foo3"},
{group: "A", title: "foo4"},
{group: "B", title: "foo5"},
{group: "B", title: "foo6"},
{group: "B", title: "foo7"}
];
var second_original = [
{group: null, title: "bar1"},
{group: null, title: "bar2"},
{group: null, title: "bar3"},
{group: null, title: "bar4"},
{group: null, title: "bar5"},
{group: null, title: "bar6"},
{group: null, title: "bar7"}
];
我很难概念化如何将它们映射到以下结构:
var first_copy = [
{
header: "A",
items: [
{group: "A", title: "foo1"},
{group: "A", title: "foo2"},
{group: "A", title: "foo3"},
{group: "A", title: "foo4"}
]
},
{
header: "B",
items: [
{group: "B", title: "foo5"},
{group: "B", title: "foo6"},
{group: "B", title: "foo7"}
]
}
];
var second_copy = [
{
header: null,
items: [
{group: null, title: "bar1"},
{group: null, title: "bar2"},
{group: null, title: "bar3"},
{group: null, title: "bar4"},
{group: null, title: "bar5"},
{group: null, title: "bar6"},
{group: null, title: "bar7"}
]
}
];
我尝试使用 .forEach()
:
function getRemappedObject(contentList) {
val lastGroup = null;
var currentIndex = 0;
var groups = [];
contentList.forEach(function(item) {
if (!groups[currentIndex]) {
groups.push({items: [item]});
} else {
groups[currentIndex].items.push(item);
}
groups[currentIndex].header = item.group;
if (item.group && item.group !== lastGroup) {
lastGroup = item.group;
currentIndex++;
}
});
return groups;
}
但这在规范的 header 部分惨遭失败。我认为这是睡眠不足,但我很好奇是否有更好的方法。我想在没有 Underscore 或 Lodash 的情况下解决它。请使用 ECMAScript 5 或 6。
如何将上述结构映射到预期输出?
使用另一个 Array 来跟踪 header 值;
function organise(arr) {
var headers = [], // an Array to let us lookup indicies by group
objs = [], // the Object we want to create
i, j;
for (i = 0; i < arr.length; ++i) {
j = headers.indexOf(arr[i].group); // lookup
if (j === -1) { // this entry does not exist yet, init
j = headers.length;
headers[j] = arr[i].group;
objs[j] = {};
objs[j].header = arr[i].group;
objs[j].items = [];
}
objs[j].items.push( // create clone
{group: arr[i].group, title: arr[i].title}
);
}
return objs;
}
var first_copy = organise(first_original);
如果您可以假设分组将始终是 string 即永远不会 null
您可以通过键而不是 indexOf 查找更有效地完成它
ES6 可能会让你更像这里的其他解决方案一样通过例如a Map(WeakMap 不允许基元作为键)