使用Ramda查找子元素索引及对应父元素索引,优化实现并去箭头函数
基于Ramda优化查找子元素索引与父section索引的实现
问题分析
你当前的两段Ramda实现存在以下可优化点:
- 第一段
pathToField的reduce逻辑错误:未使用累积值found,导致无论前面的section是否匹配,最终都会返回最后一个section的处理结果,无法正确定位目标元素。 - 两段实现都存在箭头函数,且函数组合可以更简洁,减少冗余逻辑。
优化后的无箭头函数实现
以下是完全基于Ramda函数组合、无箭头函数的实现,同时修复了逻辑问题:
const sections = [ { key: 'first', data: [ { key: 'a' }, { key: 'b' } ] }, { key: 'second', data: [ { key: 'c' }, { key: 'd' } ] }, { key: 'third', data: [ { key: 'e' }, { key: 'f' } ] }, ] // 生成带父索引的section数组,结构为 [父索引, 原section对象] const indexedSections = addIndex(map)(pair) // 根据key获取子元素在section.data中的索引 const getChildIndex = useWith(findIndex, [propEq('key', __), prop('data')]) // 判断带索引的section是否包含目标key的子元素 const hasTargetKey = curry(useWith(compose(gt(__, -1), getChildIndex), [__, identity])) // 找到包含目标key的带索引section const findTargetIndexedSection = curry(useWith(find, [hasTargetKey, indexedSections])) // 从找到的带索引section中提取[父索引, 子索引]的结果对 const buildResultPair = curry(useWith(pair, [head, flip(getChildIndex)(__)])) // 组合所有逻辑得到最终函数 const findFieldPath = compose(buildResultPair, findTargetIndexedSection) // 测试用例 findFieldPath('f', sections) // 返回 [2, 1] findFieldPath('b', sections) // 返回 [0, 1] findFieldPath('x', sections) // 返回 undefined(未找到目标时)
代码解释
indexedSections:通过addIndex(map)(pair)给每个section绑定对应的父索引,生成[索引, section]的数组结构,避免修改原section对象。getChildIndex:利用useWith将propEq('key', __)和prop('data')与findIndex结合,实现根据key查找子元素索引的功能。hasTargetKey:通过函数组合判断带索引的section是否包含目标子元素,返回布尔值。findTargetIndexedSection:找到符合条件的带索引section,作为后续提取结果的数据源。buildResultPair:从带索引section中提取父索引(head取数组第一个元素)和子索引,组合成最终需要的结果数组。findFieldPath:通过compose将所有函数串联,实现从输入key和sections到结果的完整流程。
可选:未找到时的默认值处理
如果需要在未找到目标时返回默认值(比如[-1, -1]),可以在最终组合中加入defaultTo:
const findFieldPathWithDefault = compose(defaultTo([-1, -1]), buildResultPair, findTargetIndexedSection) findFieldPathWithDefault('x', sections) // 返回 [-1, -1]
内容的提问来源于stack exchange,提问作者yurkimus
相关产品推荐
相关产品推荐

