我有以下数据结构,我试图按其父级别对这些部分进行分组。
const arr = [
{
level: '1.1',
name: 'group title 1',
},
{
level: '1.1.1',
name: 'group section 1.1.1',
},
{
level: '1.1.2',
name: 'group section 1.1.2',
},
{
level: '1.1.3',
name: 'group section 1.1.3',
},
{
level: '1.2',
name: 'group title 2',
},
{
level: '1.2.1',
name: 'group section 1.1.1',
},
{
level: '1.3',
name: 'group title 3',
},
{
level: '1.3.1',
name: 'group section 1.1.1',
},
{
level: '1.3.2',
name: 'group section 1.1.2',
},
{
level: '1.4',
name: 'group title 4',
},
{
level: '1.4.1',
name: 'group section 1.4.1',
},
{
level: '1.4.2',
name: 'group section 1.4.2',
},
{
level: '1.4.3',
name: 'group section 1.4.3',
},
];
我一直在尝试将结构更改为以下对象(对部分进行分组)。该对象具有父级别的值作为属性和部分的数组。
const obj = {
'1.1': [
{
level: '1.1.1',
name: 'group section 1.1.1',
},
{
level: '1.1.2',
name: 'group section 1.1.2',
},
{
level: '1.1.3',
name: 'group section 1.1.3',
},
],
'1.2': [
{
level: '1.2',
name: 'group title 2',
},
{
level: '1.2.1',
name: 'group section 1.1.1',
},
],
'1.3': [
{
level: '1.3',
name: 'group title 3',
},
{
level: '1.3.1',
name: 'group section 1.1.1',
},
{
level: '1.3.2',
name: 'group section 1.1.2',
},
],
'1.4': [
{
level: '1.4.1',
name: 'group section 1.4.1',
},
{
level: '1.4.2',
name: 'group section 1.4.2',
},
{
level: '1.4.3',
name: 'group section 1.4.3',
},
],
};
我的尝试没有成功。我将不胜感激如何将结构更改为上述内容。
答案 0 :(得分:9)
Array.prototype.reduce()
可用于从objects
构建arrays
。
String.prototype.match()
可用于检测strings
中的模式。
/\d+\.\d+/
匹配第一次出现的一个或多个numbers
后跟一个full stop
后跟一个或多个numbers
// Input.
const input = [{level: '1.1',name: 'group title 1',},{level: '1.1.1',name: 'group section 1.1.1',},{level: '1.1.2',name: 'group section 1.1.2',},{level: '1.1.3',name: 'group section 1.1.3',},{level: '1.2',name: 'group title 2',},{level: '1.2.1',name: 'group section 1.1.1',},{level: '1.3',name: 'group title 3',},{level: '1.3.1',name: 'group section 1.1.1',},{level: '1.3.2',name: 'group section 1.1.2',},{level: '1.4',name: 'group title 4',},{level: '1.4.1',name: 'group section 1.4.1',},{level: '1.4.2',name: 'group section 1.4.2',},{level: '1.4.3',name: 'group section 1.4.3',},]
// Group.
const group = (array) => array.reduce((o, x) => {
const key = x.level.match(/\d+\.\d+/)
if (o[key]) o[key].push(x)
else o[key] = [x]
return o
}, {})
// Output.
const output = group(input)
// Proof.
console.log(output)
答案 1 :(得分:3)
在我看来,遵循DRY原则,更优雅的方式是使用已经具有此功能的Lodash。
const group = arr =>_.groupBy(arr, x => x.level.match(/\d+\.\d+/));
_。groupBy https://lodash.com/docs#groupBy
创建一个由根据结果生成的键组成的对象 通过iteratee运行集合的每个元素。分组的顺序 值由它们在集合中出现的顺序确定。该 每个键的对应值是一个负责的元素数组 用于生成密钥。
但当然,如果您被允许使用外部库。
结果摘录
const arr = [
{
level: '1.1',
name: 'group title 1',
},
{
level: '1.1.1',
name: 'group section 1.1.1',
},
{
level: '1.1.2',
name: 'group section 1.1.2',
},
{
level: '1.1.3',
name: 'group section 1.1.3',
},
{
level: '1.2',
name: 'group title 2',
},
{
level: '1.2.1',
name: 'group section 1.1.1',
},
{
level: '1.3',
name: 'group title 3',
},
{
level: '1.3.1',
name: 'group section 1.1.1',
},
{
level: '1.3.2',
name: 'group section 1.1.2',
},
{
level: '1.4',
name: 'group title 4',
},
{
level: '1.4.1',
name: 'group section 1.4.1',
},
{
level: '1.4.2',
name: 'group section 1.4.2',
},
{
level: '1.4.3',
name: 'group section 1.4.3',
},
];
const group = arr =>_.groupBy(arr, x => x.level.match(/\d+\.\d+/));
const result = group(arr);
console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
在您的问题中,如果您还需要标题(1.1,1.2等),则上述版本包含它们并不清楚。但是如果你不想要它们,你首先需要从阵列中删除它们:
arr.filter(x => !/^\d+\.\d+$/.test(x.level))
一起
const group = arr => {
const noheaders = arr.filter(x => !/^\d+\.\d+$/.test(x.level));
return _.groupBy(noheaders, x => x.level.match(/\d+\.\d+/));
}
const arr = [
{
level: '1.1',
name: 'group title 1',
},
{
level: '1.1.1',
name: 'group section 1.1.1',
},
{
level: '1.1.2',
name: 'group section 1.1.2',
},
{
level: '1.1.3',
name: 'group section 1.1.3',
},
{
level: '1.2',
name: 'group title 2',
},
{
level: '1.2.1',
name: 'group section 1.1.1',
},
{
level: '1.3',
name: 'group title 3',
},
{
level: '1.3.1',
name: 'group section 1.1.1',
},
{
level: '1.3.2',
name: 'group section 1.1.2',
},
{
level: '1.4',
name: 'group title 4',
},
{
level: '1.4.1',
name: 'group section 1.4.1',
},
{
level: '1.4.2',
name: 'group section 1.4.2',
},
{
level: '1.4.3',
name: 'group section 1.4.3',
},
];
const group = arr => {
const noheaders = arr.filter(x => !/^\d+\.\d+$/.test(x.level));
return _.groupBy(noheaders, x => x.level.match(/\d+\.\d+/));
}
const result = group(arr);
console.log(result);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
答案 2 :(得分:0)
const obj = {};
for(const {level, name} of array) {
const key = level.split(".").slice(0, 2).join(".");
if(obj[key]) {
obj[key].push({ level, name });
} else {
obj[key] = [ { level, name } ];
}
}
要了解最新情况,以下页面可能有所帮助:
答案 3 :(得分:-1)
这是预期输出的简化版本。请检查浏览器控制台中的输出,因此代码段存在问题。谢谢。
var parent = [];
var child =[];
var result =[];
const arr = [
{
level: '1.1',
name: 'group title 1',
},
{
level: '1.1.1',
name: 'group section 1.1.1',
},
{
level: '1.1.2',
name: 'group section 1.1.2',
},
{
level: '1.1.3',
name: 'group section 1.1.3',
},
{
level: '1.2',
name: 'group title 2',
},
{
level: '1.2.1',
name: 'group section 1.1.1',
},
{
level: '1.3',
name: 'group title 3',
},
{
level: '1.3.1',
name: 'group section 1.1.1',
},
{
level: '1.3.2',
name: 'group section 1.1.2',
},
{
level: '1.4',
name: 'group title 4',
},
{
level: '1.4.1',
name: 'group section 1.4.1',
},
{
level: '1.4.2',
name: 'group section 1.4.2',
},
{
level: '1.4.3',
name: 'group section 1.4.3',
},
];
for(var i=0;i<arr.length;i++){
if(arr[i].level.length == 3){
parent.push(arr[i]);
}else{
child.push(arr[i]);
}
}
for(var j=0;j<parent.length;j++){
result[parent[j].level]=[];
for(var k=0;k<child.length;k++){
if(parent[j].level.substring(0, 3)== child[k].level.substring(0, 3)){
result[parent[j].level].push(child[k]);
}
}
}
console.log(result);
&#13;