Javascript 基于键的Ramda递归合并&x27;比赛
我有两个节点列表,形状如下:Javascript 基于键的Ramda递归合并&x27;比赛,javascript,recursion,functional-programming,ramda.js,Javascript,Recursion,Functional Programming,Ramda.js,我有两个节点列表,形状如下: interface TreeNode { data: { name: string, sharedProp: boolean, oldProp: boolean }, children: TreeNode[], parents: TreeNode[], thereAreSomeShallowProps: any, } 完整的数据集将是TreeNode 我想要的是有一个函数,我可
interface TreeNode {
data: {
name: string,
sharedProp: boolean,
oldProp: boolean
},
children: TreeNode[],
parents: TreeNode[],
thereAreSomeShallowProps: any,
}
完整的数据集将是TreeNode
我想要的是有一个函数,我可以遍历这棵树,将changes
树中的更改合并到基本树中。它需要的一些功能:
- 匹配指定键的值(在本例中支持多级键),并合并匹配项
- 可能使用
和flatten
groupBy
- 可能使用
- 当对象的值是数组时,递归
- 抗循环引用
- 能够处理非常大的对象(至少超过100k个节点)
applySpec
groupBy
mergeWithKey
mergeDeepWithKey
通过一些测试,可以更好地解释我试图实现的目标。虽然这可能不是最好的方法,但我们可以利用家里现有的工具轻松构建。(在我的例子中,我在这里自由使用了Ramda函数,因为问题被标记为Ramda(免责声明:我是Ramda的作者),但下面我展示了一个替代版本,它从头开始构建所需的实用程序函数 这就假设您的更改对象将是和/或将包括稀疏数组。如果没有,你打算如何匹配 我的做法如下:
//帮助程序或实用程序函数
函数*getpath(o,p=[])){
如果(Object(o)!==o | | Object.keys(o).length==0)产生p
if(对象(o)==o)
for(设k为对象键(o))
收益率*getpath(o[k],…p,Number.isInteger(Number(k))?Number(k):k])
}
常量所有路径=(o)=>[…获取路径(o)]
//主要功能
常量applyChanges=(对象,更改)=>
reduce((o,p)=>assocPath(p,path(p,changes),o),obj,allpath(changes))
//样本数据
常数基=[
{a:1,b:{c:11,d:[{e:100},{e:111}]},
{a:2,b:{c:22,d:[{e:200},{e:222}]},
{a:3,b:{c:33,d:[{e:300},{e:333}]},
]
常数三角洲=[
{a:8,b:{d:[,{e:888}]},
,
{b:{c:99,d:[{e:999},]},
]
//示范
控制台日志(
应用更改(基础、三角洲)
)
const{reduce,assocPath,path}=R
这个问题最好分成更小的部分,我不知道为什么需要使用Ramda来解决这个问题?Ramda是一个库,而不是一个框架。您对数组的更改是否稀疏?更好的是,你能提供一个小样本输入和预期的输出吗?@ScottSauyet,它有一些testsHm,我应该注意,主对象有超过100k个节点,每个节点都引用它的父节点和子节点。我担心,由于循环引用,尝试查找所有路径可能会有问题,并且遍历整个对象可能会花费太长时间(它需要对频繁的用户操作做出非常灵敏的响应),如果您的更改集有那么多节点,那么这可能是个问题。我不认为这是主要目标的问题。但是父/子链接可能会接受这种方法,或者至少需要一些自定义的getpath
——跳过子节点。这些更改可能不会有那么多节点,但主树不认为有可能对这种方法进行增强,以处理这些问题。但最有效的方法是偏离Ramda的非修改理想。我想我可能可以使用一个参数来定义它应该或不应该遵循的键,以避免循环引用问题