Javascript Typescript-在多维对象中查找匹配的键和路径

Javascript Typescript-在多维对象中查找匹配的键和路径,javascript,typescript,object,recursion,multidimensional-array,Javascript,Typescript,Object,Recursion,Multidimensional Array,简言之;如何在多个对象中检索共享键的所有值 更长: 我得到了以下对象,它们存储在一个名为collection的数组中: [ names: { "one": "square"; "two": { "three": "circle" "four": { "five": "triangle" } } }

简言之;如何在多个对象中检索共享键的所有值

更长: 我得到了以下对象,它们存储在一个名为
collection
的数组中:

[
    names: {
        "one": "square";
        "two": {
            "three": "circle"
            "four": {
                "five": "triangle"
                }
            }
        }
    shapes: {
        "one": "[]";
        "two": {
            "three": "()"
            "four": {
                "five": "/\"
                }
            }
        }
]
我在Angular(v8.x.x)中创建了一个菜单系统,可以从
名称
对象中读取键。 当我点击“circle”菜单项时,我希望获得键值对及其路径,以便在编辑窗口中使用。每个项目都需要这样做。 例:

我曾试图自己创建一个递归函数,但到目前为止还没有得到任何可行的结果。 我还尝试了Scott的惊人示例,尽管angular/typescript不幸地在
assocPath()中的
ps
定义上抛出了一个错误:

此外,我还参考了以下答案:

1:

2:

第一个在声明前使用的
path
是一个块作用域变量,因此有一个错误,我目前正在对方案中的第二个进行故障排除。

Update 当我最初写这篇文章时,我显然是在剪切和粘贴其他地方的一些代码,因为我包含了两个根本没有被使用的函数。它们现在被移除了

我还在下面的答案中添加了一个解释,说明如何逐步将其中一个函数从ES5样式转换为现代JS版本。我相信ES6+是一个重大的改进,我喜欢这个函数,因为我写得更好,但是对于那些学习现代JS的人来说,这样的解释可能会有用

更新后的原始答案如下,然后是这些转换步骤


我真的不清楚你在找什么。我的最佳猜测是,您希望接受一个如上所述的对象数组,并返回一个函数,该函数接受一个值,如
“circle”
“()”
,并返回其中一个对象上该值的路径,即
['two','three']
。但这一猜测可能远远不够

以下是一个基于几个可重用函数的版本:

//助手
常量路径=(ps=[],obj={})=>
ps.reduce((o,p)=>(o |{})[p],obj)
常量findLeafPaths=(o,path=[[]])=>
o的类型==‘对象’
? Object.entries(o).flatMap(
([k,v])=>findleafpath(v,path).map(p=>[k,…p])
) 
:路径
//主要功能
const makeSearcher=(xs)=>{
const structure=xs.reduce(
(a,x)=>findleafpath(x).reduce((a,p)=>({…a[path(p,x)]:p}),a),
{}
)
return(val)=>structure[val]| |[]//其他内容?还是抛出错误?
}
//示范
常量objs=[
{1:“正方形”,2:{3:“圆形”,4:{5:“三角形”}},
{1:[]、2:{3:(())、4:{5:/\\\\'}}
]
const searcher=makeSearcher(objs)
console.log(searcher(“()”)/~>['two','three']
console.log(searcher('circle'))/~>['two','three']
console.log(searcher('triangle'))/~>['two',four','five']
console.log(搜索器('[]')/~>['one']
console.log(searcher('heptagon'))/~>[]

我已经解决了当前的跳闸点

const assocPath = ([p = undefined, ...ps], val, obj) => 
  p == undefined
    ? obj
    : assoc (p, ps.length ? assocPath ([ps], val, obj[p] || {}) : val, obj)

功能现在可以按预期工作。如果只给出希望查找的值,则来自
searcher()
的结果还可以返回单个路径。e、 g.
searcher(“圆圈”)
返回:
[“一”、“二”、“三”]

您的尝试在哪里?我已经尝试了许多
的搜索结果。。。在…
循环中,尽管大多数会返回未定义的值,可能是因为尝试使用索引,或者变量传递不正确。在这方面我有点不知所措。听起来你需要一个递归函数。你能给出一个输入和输出的例子吗?正确。输入将是一个集合对象/数组,该集合对象/数组依次包含三个(或更多)对象。e、 g.如果输出应该是
key2-1
的名称/路径,则函数必须搜索
one.key1.key2.key2-1=john
two.key1.key2.key2-1=alice
。路径和键不会改变,但“目标”键取决于用户在菜单中选择的内容(所述菜单反映对象的键)。我曾尝试创建一个递归函数,但它很难继续超过键1,这可能是因为括号表示法不适合这种情况。(
one[key1][key2][key2-1]
)您想要的输出结构是什么?另外,请分享你的一些尝试。即使它是不完整的,它也能帮助其他人理解你想做什么。我对不清楚的描述表示诚挚的歉意,我自己已经读了好几遍,也不能很好地解释它。您的解释是正确的,我也一直在尝试将您的代码融入其中,尽管有些困难。(毕竟,angular+typescript是相当挑剔的)我认为“结构”目前还不错,也不能真正想出一个合适的替代方案。@eymas:添加了一个很长的解释。还删除了我从另一个问题中粘贴的一些函数,这些函数实际上没有被使用。很抱歉。关于这一点的详细解释与我设法提取的内容相匹配,并且保留了相当好的功能!谢谢你的大力支持!就我个人而言,我更喜欢较短的表示法。如果这是您需要支持的内容,那么您应该每次都返回数组,而不是添加检查,无论是没有路径、一条路径还是多条路径。这可以通过将传递给reduce的
(a,p)=>({…a[path(p,x)]:p})函数替换为
(a,p)=>({…a[path(p,x)]:[…(a[path(p,x)]|[],p]}
或等价地,
(a,p)=>({…a[path(p,x)]:(a[path(p,x)]。[]
。这确实更有意义,是的。谢谢你的快速回复!这是我需要支持的东西,同时也需要能够找到空字符串
|----------
|three: 
|circle
|----------
|three:
|()
|----------
Argument of type 'any[]' is not assignable to parameter of type '[any, ...any[]]'.
      Property '0' is missing in type 'any[]' but required in type '[any, ...any[]]'.
const assocPath = ([p = undefined, ...ps], val, obj) => 
  p == undefined
    ? obj
    : assoc (p, ps.length ? assocPath ([ps], val, obj[p] || {}) : val, obj)