Javascript 如何循环对象并创建树对象
我有一个平面对象和一个数组,我需要从中构造一个树状对象Javascript 如何循环对象并创建树对象,javascript,loops,object,Javascript,Loops,Object,我有一个平面对象和一个数组,我需要从中构造一个树状对象 choices: ['choice1', 'choice2', 'choice3']; items: [ { choice1: 'taste', choice2: 'good', choice3: 'green-lemon' }, { choice1: 'taste', choice2: 'bad', choice3: '
choices: ['choice1', 'choice2', 'choice3'];
items: [
{
choice1: 'taste',
choice2: 'good',
choice3: 'green-lemon'
},
{
choice1: 'taste',
choice2: 'bad',
choice3: 'green-lemon'
}
];
数组描述树中每个选项的级别。我不知道以后会有多少选择、项目或级别
如何获取以下对象:
output: {
taste: {
good: {
green-lemon:1
},
bad: {
green-lemon:1
}
}
}
我需要得到一个对象,描述每个级别上有多少项。在本例中,这是选项1:1代码>选择2:2
和每个选择3:1
有没有关于如何构建循环以获得此结果的建议?我认为最好的解决方案是使用递归的循环。我增加了示例中模型的大小,以显示它与n个级别的关系。使用javascript控制台检查输出
var choices = ['choice1', 'choice2', 'choice3'];
var items = [{
choice1: 'taste',
choice2: 'good',
choice3: 'green-lemon'
}, {
choice1: 'taste',
choice2: 'bad',
choice3: 'green-lemon'
},
{
choice1: 'taste',
choice2: 'ok',
choice3: 'green-lemon'
},
{
choice1: 'taste',
choice2: 'ok',
choice3: 'green-lemon'
}];
function IsLastLevel(levelIndex) {
return (levelIndex == choices.length - 1);
}
function HandleLevel(currentItem, currentLevel, nextChoiceIndex) {
var nextLevelName = currentItem[choices[nextChoiceIndex]];
if (typeof currentLevel[nextLevelName] === 'undefined') {
currentLevel[nextLevelName] = {};
}
if (IsLastLevel(nextChoiceIndex)) {
if (currentLevel[nextLevelName] > 0) {
currentLevel[nextLevelName]++;
} else {
currentLevel[nextLevelName] = 1;
}
} else {
var goOneDeeper = nextChoiceIndex + 1;
HandleLevel(currentItem, currentLevel[nextLevelName], goOneDeeper);
}
}
var output = {};
for(var itemIndex in items)
{
var item = items[itemIndex];
HandleLevel(item, output, 0);
}
console.log(output);
Brainwipe已经给出了一个非常清晰的答案,但我想我还是会试试我的手。该解决方案的工作原理是递归地逐级减少项目列表,直到它到达叶节点
功能选项树(项目、选项){
//如果没有选择,则返回空对象。
if(!choices.length)返回{};
var choice=choices.shift();
//构建树的当前级别。
var级别=items.reduce(函数(节点,项){
var值=项目[选择];
//如果是分支节点,则添加项;如果是叶节点,则设置为1。
节点[值]=(选项.长度)
?(节点[值]| |[]).concat(项目)
: 1;
返回节点;
}, {});
//如果没有剩余的选项,则返回。
如果(!choices.length)返回级别;
//递归地构造下一层。
for(级别中的变量节点)
level[node]=choiceTree(level[node],choices.slice());
回报水平;
}
还会有更多的级别吗?这个数据集会扩展吗?choices
数组是用来描述树中每个选项的级别的吗@brainwipe的问题也与正确的解决方案有关。@brainwipe:可能只有2个级别的选择,可能有5个级别的选择。“选项”数组和“项目”对象在运行时不会更改。@JordanGray:items包含更多数据。选项数组将树描述为level0是第一项,level0是最后一项。@这很有用。你想作为数组的结果显示树、物品计数还是两者都显示?也非常感谢。代码要少得多,但更难阅读。我还没有使用reduce,但肯定会看看它。谢谢。Array.reduce
真的很酷而且没有得到充分利用,你一定要好好读一读!)它所做的只是将数组“缩减”为单个值;你可以,但我认为额外的代码更混乱。IE 8及以下版本不支持它,但它是。