这是我正在使用的平面对象,它有更多的结果,~6800。我一直试图将它转换为嵌套树(如下面列出的)大约13个小时了,我真的迷路了。
[
{
"make": "Acura",
"classification": "Mid SUV",
"segment": "Competitive Trucks",
"model": "RDX",
"catalogDetail": "RDX_SUV_4_Gasoline_2013_Base w/Tech_FWD_3.5_6_105.7_Automatic"
},
{
"make": "Acura",
"classification": "Midsize Car",
"segment": "Competitive Cars",
"model": "TSX",
"catalogDetail": "TSX_Sedan_4_Gasoline_2012_Base w/Tech_FWD_2.4_4_106.4_Automatic"
},
{
"make": "Aston Martin",
"classification": "Compact Car",
"segment": "Competitive Cars",
"model": "DB11",
"catalogDetail": "DB11_Convertible_2_Gasoline_2019_Volante_RWD_4.0_8_110.4_Automatic"
}
]
我想做的是将这个平面对象构建成一个嵌套结构,如下所示:
[
{
"make": [
{ "Acura",
"classification": [{
"Mid SUV",
"segment": [{
"Competitive Trucks",
"model": [{
"RDX",
"catalogDetail": [{
"RDX_SUV_4_Gasoline_2013_Base w/Tech_FWD_3.5_6_105.7_Automatic"
}]
}]
}],
"Midsize Car",
"segment": [{
"Competitive Cars",
"model": [{
"TSX",
"catalogDetail": [{
"TSX_Sedan_4_Gasoline_2012_Base w/Tech_FWD_2.4_4_106.4_Automatic"
}]
}]
}]
}],
}
]
},
{
"make": [
{ "Aston Martin",
"classification": [{
"Compact Car",
"segment": [{
"Competitive Cars",
"model": [{
"DB11",
"catalogDetail": [{
"DB11_Convertible_2_Gasoline_2019_Volante_RWD_4.0_8_110.4_Automatic"
}]
}]
}]
}]
}
]
}
]
其中结构福尔斯嵌套结构,如:制造--〉分类--〉细分--〉型号--〉目录详细信息。因此,将有多个汽车制造商,福特、凯迪拉克等。多个分类,每个制造商下有多个不同的细分。
我试过了
this._servicesService.getHierarchy().subscribe(data => {
console.log(data)
/* this.data = data;*/
/* this.dataStore = data;*/
let distinctSeg = [...new Set(data.map(x => x.segment))];
let distinctClass = [...new Set(data.map(x => x.classification))];
let distinctMod = [...new Set(data.map(x => x.model))];
let distinctCd = [...new Set(data.map(x => x.catalogDetail))];
const newData = [];
data.forEach(e => {
if (newData.length == 0) {
newData.push({
make: e.make,
segment: e.segment,
classification: e.classification,
model: [e.model],
catalogDetail: [e.catalogDetail]
});
} else {
let foundIndex = newData.findIndex(fi => fi.make === e.make, fi => fi.segment = e.segment);
if (foundIndex >= 0) {
/* newData[foundIndex].make.push(e.make),*/
/* newData[foundIndex].segment.push(e.segment),*/
/* newData[foundIndex].classification.push(e.classification),*/
newData[foundIndex].model.push(e.model);
newData[foundIndex].catalogDetail.push(e.catalogDetail);
} else {
newData.push({
make: e.make,
segment: distinctSeg,
classification: distinctClass,
model: [e.model],
catalogDetail: [e.catalogDetail]
});
}
}
});
console.log(newData);
})
这为模型、细分市场和类给予了不同的值,(由于某种原因,不是model或catalogDetail),但是嵌套结构并不存在,我真的不知道如何继续。我已经看了很多例子,我真的没有成功地应用前面列出的任何一条路线。任何见解或提示都将非常感谢。我附上了一张图片,以便在语法错误的情况下更好地可视化最终所需的输出。tree
3条答案
按热度按时间plicqrtu1#
对于输入-输出,看起来像这样:
其中
collect()
是一个函数,它接受一个对象数组和这些对象的键列表。(它至少需要一个键,并且输入对象在这些键上应该有string
值。)我们的工作是实现collect()
。我采用的方法是递归的;第一种是基本情况,只对一个键调用
collect(inp, key1)
。在这种情况下,我们只想返回一个包含key1
键的值的数组,我们可以通过map
ping得到输入数组;即inp.map(v => v[key1])
。然后递归一步:当您使用多个键调用
collect(inp, key1, ...keyRest)
时,输出将具有与inp
元素的key1
属性相对应的键。在上面的示例中,如果我们调用collect(inp, "a", ...keyRest)
,则输出将具有键x
和y
。对于x
键,我们将inp
中a
属性为"x"
的元素收集到另一个数组inpX
中,则x
键处的值将为collect(inpX, ...keyRest)
。类似地,对于y
键。也就是说,我们将输入数组拆分为与key1
键处的值相对应的子数组,然后对每个子数组求值collect(subArr, ...keyRest)
。这是对算法的口头描述,让我们看看它对
collect()
的 typings 意味着什么:这里我们说
collect()
是一个generic函数,它接受对象类型为T
的元素数组和元组类型为K
的键列表。我们对arr
进行约束,使arr
数组的每个元素都是T
类型,并且在K
中的每个关键元素处都具有string
属性我们约束K
,使得每个关键元素都是T
的某个关键字。我们返回
Collect<K>
类型的值,其中Collect<K>
本身是一个递归条件类型,表示具有嵌套string
索引签名的对象,其基本情况值类型为string[]
。现在开始实施:
因为函数的调用签名返回一个通用的条件类型,所以最简单的方法是让函数成为一个单调用签名重载,这样就可以对实现进行宽松的检查。这意味着我们在实现之前有一个声明的调用签名:
好吧,我们来测试一下:
这很有效!你的例子是:
那也行!
Playground代码链接
mo49yndu2#
我建议您使用Array.reduce方法。
此方法允许您轻松地将JS数组转换为对象。
您可以执行以下操作:
gg58donl3#
就像Avrham说的,你可以使用reduce。
您可以在以下方式中使用:
但是我认为管理这种树视图并不容易。通常你有一个树视图,所有的数组都是“孩子”。所以我建议创建一个函数
您可以使用像
您可以在this stackblitz中看到这两种方法