如何循环通过对象并创建树对象
How to loop through Object and create a tree Object
我有一个平面对象和一个数组,我需要从中构建一个树状对象。
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
}
}
}
我需要得到一个对象来描述每个级别上有多少项。在该示例中,这是choice1: 1;
choice2: 2
和每个choice3: 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);
JsFiddle演示
Brainwipe已经给出了一个非常明确的答案,但我想我无论如何都会尝试一下。该解决方案通过递归地逐级减少项目列表,直到到达叶节点。
function choiceTree(items, choices) {
// Return empty object if there were no choices.
if (!choices.length) return {};
var choice = choices.shift();
// Construct the current level of the tree.
var level = items.reduce(function(node, item) {
var value = item[choice];
// Add item if branch node or set to 1 if leaf node.
node[value] = (choices.length)
? (node[value] || []).concat(item)
: 1;
return node;
}, {});
// Return if there are no remaining choices.
if (!choices.length) return level;
// Recursively construct the next level.
for (var node in level)
level[node] = choiceTree(level[node], choices.slice());
return level;
}
jsFiddle演示
相关文章:
- JavaScript名称空间和对象创建
- 从不同的对象创建阵列
- Nodejs-从对象创建可读流
- Javascript对象创建实践
- 插件SDK中的动态或计算对象创建
- 为json对象创建一个动态表
- 对象.创建解释
- 从对象创建嵌套数组失败
- 从JSON对象创建具有超链接的HTML表
- 如何将文档对象创建为HTML页面
- 创建一个类,该类使用es6类语法将Function对象创建为实例
- KineticJS在对象创建(NOOB)后更改属性
- 对象创建中的JavaScript && notation
- Javascript对象创建-创建许多对象
- 从另一个JSON对象创建JSON对象
- 使用linq.js从多个对象创建JSON对象数组
- 如何使用Immutable.js从javascript原始对象创建记录映射
- 在fabric.js中初始化对象创建的子类
- Angularfire:从$FirebaseObject的子对象创建$FirebaseObject
- 为JSON对象创建CRUD