javascript - 使用 lodash 或其他 lib 引用其他属性的 Javascript 递归转换对象
问题描述
我想转换通过其属性相互引用的javascript对象,
说我有这个对象
{
apple: {
banana: [1,2,3],
cherry: [4,5,6],
},
banana: {
date: [7],
cherry: [8,9],
elderberry: [10, 11],
},
cherry: {
date: [7],
fig: [12,13],
},
date: {
fig: [11,14],
},
},
我想把那个对象变成这个
{
apple: {
banana: [1,2,3],
cherry: [4,5,6, 8,9],
date: [7],
elderberry: [10, 11],
fig: [11,14, 12,13],
},
banana: {
cherry: [8,9],
elderberry: [10, 11],
fig: [11,14, 12,13],
date: [7],
},
cherry: {
date: [7],
fig: [11,14, 12,13],
},
date: {
fig: [11,14],
},
}
在那个例子中,苹果的樱桃属性有 [4,5,6,8,9],[4,5,6] 来自苹果,[8, 9] 来自香蕉,因为苹果引用了香蕉和香蕉有参考樱桃,因此它将被合并到[4,5,6,8,9]
而且最终的数组实际上是唯一的值
所以想法是它会递归合并其他组件值,使用 lodash 或其他库是可以的~
解决方案
我将首先创建一个存储相反关系的结构,即从孩子到父母。
然后对于每个键/数组对,沿着路径(通过新结构)向上到达其祖先,并将数组添加到那里的相同键中。我为此选择了使用显式堆栈变量的遍历,但它与递归 DFS 遍历一样好。
最后再次访问所有数组以删除重复项。
function complete(data) {
// Create child-parent relationships:
const parents = {};
for (const parent in data) {
for (const child in data[parent]) {
(parents[child] = parents[child] || []).push(parent);
}
}
// Tree traveral to copy child array into same key in ancestors
const result = {};
for (const parent in data) {
for (const child in data[parent]) {
const arr = data[parent][child];
const visited = new Set;
const stack = [parent];
while (stack.length) {
const node = stack.pop();
if (visited.has(node)) continue;
visited.add(node);
((result[node] = result[node] || {})[child] = result[node][child] || []).push(...arr);
stack.push(...parents[node] || []);
}
}
}
// Remove duplicate values from the arrays
for (const parent in result) {
for (const child in result[parent]) {
result[parent][child] = [...new Set(result[parent][child])];
}
}
return result;
}
// Example call with data from the question:
const data = {apple: {banana: [1,2,3],cherry: [4,5,6],},banana: {date: [7],cherry: [8,9],elderberry: [10, 11],},cherry: {date: [7],fig: [12,13],},date: {fig: [11,14],},};
const result = complete(data);
console.log(result);
推荐阅读
- python - 我可以在 Python 脚本中运行 SBT 任务吗?
- r - 如何根据R中的最后一个值使向量选择3个可能的值
- cakephp-3.0 - 如何验证 cakephp 表单中输入的日期?
- python - 在熊猫的新列中移动行中的值
- javascript - 从引导导航栏滚动到元素
- sql-server - Service Pack 到 SQL Server 容器
- c# - 以编程方式从文件打开网页并单击链接以处理响应 C#
- javascript - 使用 HTML Div 的 Javascript/Jquery onClick 不起作用
- javascript - 脚本属性 text/some-library 的映射如何工作
- javascript - Javascript双向参考问题