在Javascript中将结构化字符串数组转换为多级对象

在Javascript中将结构化字符串数组转换为多级对象,javascript,ecmascript-6,ecmascript-2016,Javascript,Ecmascript 6,Ecmascript 2016,我有一个结构化字符串数组,它的连接方式是|,格式可以自我划分为多个级别。我想将其转换为具有多个级别的结构化对象 输入: [ "clothes|tshirt|tshirt-for-kids", "clothes|coat|raincoat", "clothes|coat|leather-coat", "clothes|tshirt|tshirt-for-men", "clothes|tsh

我有一个结构化字符串数组,它的连接方式是
|
,格式可以自我划分为多个级别。我想将其转换为具有多个级别的结构化对象

输入:

[
  "clothes|tshirt|tshirt-for-kids",
  "clothes|coat|raincoat",
  "clothes|coat|leather-coat",
  "clothes|tshirt|tshirt-for-men",
  "clothes|tshirt|tshirt-for-men|luxury-tshirt",
]
预期产出:

{
   clothes: {
     tshirt: {
       tshirt-for-kids: {},
       tshirt-for-men: {
         luxury-tshirt: {}
       }
     },
     coat: {
       raincoat: {}
       leather-coat: {}
     }
   }
}

非常简单的任务-只需枚举数组并创建相关的对象键:

var myArray=[
“衣服| T恤|儿童T恤”,
“衣服|外套|雨衣”,
“衣服|外套|皮大衣”,
“衣服| T恤|男士T恤”,
“衣服| T恤|男士T恤|豪华T恤”,
]
var result={},级别,当前,温度;
while(myArray.length>0)
{
levels=myArray.pop().split(“|”);
温度=结果;
而(levels.length>0)
{
电流=电平。移位();
如果(!(温度中的电流))温度[电流]={};
温度=温度[电流];
}
}

控制台日志(结果)非常简单的任务-只需枚举数组并创建相关的对象键:

var myArray=[
“衣服| T恤|儿童T恤”,
“衣服|外套|雨衣”,
“衣服|外套|皮大衣”,
“衣服| T恤|男士T恤”,
“衣服| T恤|男士T恤|豪华T恤”,
]
var result={},级别,当前,温度;
while(myArray.length>0)
{
levels=myArray.pop().split(“|”);
温度=结果;
而(levels.length>0)
{
电流=电平。移位();
如果(!(温度中的电流))温度[电流]={};
温度=温度[电流];
}
}
控制台日志(结果)您可以尝试以下方法:

const输入=[
“衣服| T恤|儿童T恤”,
“衣服|外套|雨衣”,
“衣服|外套|皮大衣”,
“衣服| T恤|男士T恤”,
“衣服| T恤|男士T恤|豪华T恤”,
];
函数convertstrtobject(str、sep、obj){
const sepIndex=str.indexOf(sep);
如果(sepinex==-1){
obj[str]=obj[str]|{};
}否则{
const key=str.substring(0,sepinex);
obj[key]=obj[key]|{};
convertstrtobject(str.substring(sepinex+1)、sep、obj[key]);
}
}
常量all={};
for(设i=0;i您可以尝试以下方法:

const输入=[
“衣服| T恤|儿童T恤”,
“衣服|外套|雨衣”,
“衣服|外套|皮大衣”,
“衣服| T恤|男士T恤”,
“衣服| T恤|男士T恤|豪华T恤”,
];
函数convertstrtobject(str、sep、obj){
const sepIndex=str.indexOf(sep);
如果(sepinex==-1){
obj[str]=obj[str]|{};
}否则{
const key=str.substring(0,sepinex);
obj[key]=obj[key]|{};
convertstrtobject(str.substring(sepinex+1)、sep、obj[key]);
}
}
常量all={};
for(设i=0;i一个带有
eval的衬里
使用
eval
计算字符串,如下所示:

'o["clothes"]??={}'
'o["clothes"]["tshirt"]??={}'
'o["clothes"]["tshirt"]["tshirt-for-kids"]??={}'
const
数据=[“衣服| T恤|儿童T恤”,“衣服|外套|雨衣”,“衣服|外套|皮衣”,“衣服| T恤|男士T恤”,“衣服| T恤|男士T恤|豪华T恤”],
arr=data.map((d)=>d.split(“|”),
res=arr.reduce((r,a)=>(a.forEach((k,i)=>eval(`r[“${a.slice(0,i+1).join(''][')}')??={}'),r),{});
console.log(res)
一个带有
eval的衬里
使用
eval
计算字符串,如下所示:

'o["clothes"]??={}'
'o["clothes"]["tshirt"]??={}'
'o["clothes"]["tshirt"]["tshirt-for-kids"]??={}'
const
数据=[“衣服| T恤|儿童T恤”,“衣服|外套|雨衣”,“衣服|外套|皮衣”,“衣服| T恤|男士T恤”,“衣服| T恤|男士T恤|豪华T恤”],
arr=data.map((d)=>d.split(“|”),
res=arr.reduce((r,a)=>(a.forEach((k,i)=>eval(`r[“${a.slice(0,i+1).join(''][')}')??={}'),r),{});

log(res)
假设您打算收集属性,所有属性都有一个空对象作为叶节点

//输入
常量输入=[
“衣服| T恤|儿童T恤”,
“衣服|外套|雨衣”,
“衣服|外套|皮大衣”,
“衣服| T恤|男士T恤”,
“衣服| T恤|男士T恤|豪华T恤”,
];
//在这里,我们收集属性
const out={};
//映射输入数组,在|
input.map(i=>i.split(“|”))
.filter(a=>a.length>0)//不允许在输入中包含空行
.forEach(a=>{//处理每个属性名数组
//从最外层开始
设p=输出;
//迭代属性
用于(常数v/a){
//如果尚未创建属性,请创建该属性
如果(!p.hasOwnProperty(v)){
p[v]={};
}
//移动到嵌套级别
p=p[v];
}
});
//让我们看看我们创造了什么

控制台。注销假设您打算收集属性,所有属性都有一个空对象作为叶节点

//输入
常量输入=[
“衣服| T恤|儿童T恤”,
“衣服|外套|雨衣”,
“衣服|外套|皮大衣”,
“衣服| T恤|男士T恤”,
“衣服| T恤|男士T恤|豪华T恤”,
];
//在这里,我们收集属性
const out={};
//映射输入数组,在|
input.map(i=>i.split(“|”))
.filter(a=>a.length>0)//不允许在输入中包含空行
.forEach(a=>{//处理每个属性名数组
//从最外层开始
设p=输出;
//迭代属性
用于(常数v/a){
//如果尚未创建属性,请创建该属性
如果(!p.hasOwnProperty(v)){
p[v]={};
}
//移动到嵌套级别
p=p[v];
}
});
//让我们看看我们创造了什么

控制台。注销
已经提出了许多解决方案,但我很惊讶没有一个涉及到
reduce()
——这对我来说似乎是更惯用的解决方案

var array = [
    "clothes|tshirt|tshirt-for-kids",
    "clothes|coat|raincoat",
    "clothes|coat|leather-coat",
    "clothes|tshirt|tshirt-for-men",
    "clothes|tshirt|tshirt-for-men|luxury-tshirt",
]

var object = array.reduce(function (object, element) {
    var keys = element.split("|")

    keys.reduce(function (nextNestedObject, key) {
        if (!nextNestedObject[key]) nextNestedObject[key] = {}
        return nextNestedObject[key]
    }, object)

    return object
}, {})

console.log(object)

已经提出了许多解决方案,但我很惊讶没有一个涉及到
reduce()
——这对我来说似乎是更惯用的解决方案

var array = [
    "clothes|tshirt|tshirt-for-kids",
    "clothes|coat|raincoat",
    "clothes|coat|leather-coat",
    "clothes|tshirt|tshirt-for-men",
    "clothes|tshirt|tshirt-for-men|luxury-tshirt",
]

var object = array.reduce(function (object, element) {
    var keys = element.split("|")

    keys.reduce(function (nextNestedObject, key) {
        if (!nextNestedObject[key]) nextNestedObject[key] = {}
        return nextNestedObject[key]
    }, object)

    return object
}, {})

console.log(object)

你可以使用斯科特答案中的
addPath()
思想,比如:@NickParsons你能把它作为答案发布吗?它主要是斯科特的代码,所以我不知道