搜索对象的嵌套数组并返回所有匹配项的完整路径

我想搜索深度嵌套的对象数组并返回所有匹配对象的路径。我已经部分解决了问题,但代码仅返回第一个匹配对象的路径。请查看输入、预期输出和代码本身。我已在预期输出部分评论了所需的逻辑。


提前致谢。请帮帮我。


输入数据


   [

   {

      "label":"Home",

      "key":"home",

      "level":1,

      "children":[

         {

            "label":"Indoor Furniture",

            "key":"furniture",

            "level":2,

            "children":[

               {

                  "label":"Chair",

                  "key":"chair",

                  "level":3

               },

               {

                  "label":"Table",

                  "key":"table",

                  "level":3

               },

               {

                  "label":"Lamp",

                  "key":"lamp",

                  "level":3

               }

            ]

         }

      ]

   },

   {

      "label":"Outdoor",

      "key":"outdoor",

      "level":1,

      "children":[

         {

            "label":"Outdoor Furniture",

            "key":"furniture",

            "level":2,

            "children":[

               {

                  "label":"Trampoline",

                  "key":"trampoline",

                  "level":3

               },

               {

                  "label":"Swing",

                  "key":"swing",

                  "level":3

               },

               {

                  "label":"Large sofa",

                  "key":"large sofa",

                  "level":3

               },

               {

                  "label":"Medium Sofa",

                  "key":"mediumSofa",

                  "level":3

               },

               {

                  "label":"Small Sofa Wooden",

                  "key":"smallSofaWooden",

                  "level":3

               }

            ]

         },

         {

            "label":"Games",

            "key":"games",

            "level":2,

            "children":[

               

            ]

         }

      ]

   },

   {

      "label":"Refurbrished Items",

      "key":"refurbrished items",

      "level":1,

      "children":[

         

      ]

   },


慕盖茨4494581
浏览 128回答 2
2回答

PIPIONE

这看起来会做到这一点:const filterDeep = (pred) => (xs, kids) =>  xs .flatMap (    x =>       pred (x)        ? [x]      : (kids = filterDeep (pred) (x .children || [])) && kids.length        ? [{... x, children: kids}]       : []      )const testIncludes = (condition) => (obj) =>  Object .entries (condition) .every (    ([k, v]) => (obj [k] || '') .toLowerCase () .includes (v .toLowerCase ())  )const filterMatches = (obj, conditions) =>  filterDeep (testIncludes (conditions)) (obj)const input = [{label: "Home", key: "home", level: 1, children: [{label: "Indoor Furniture", key: "furniture", level: 2, children: [{label: "Chair", key: "chair", level: 3}, {label: "Table", key: "table", level: 3}, {label: "Lamp", key: "lamp", level: 3}]}]}, {label: "Outdoor", key: "outdoor", level: 1, children: [{label: "Outdoor Furniture", key: "furniture", level: 2, children: [{label: "Trampoline", key: "trampoline", level: 3}, {label: "Swing", key: "swing", level: 3}, {label: "Large sofa", key: "large sofa", level: 3}, {label: "Medium Sofa", key: "mediumSofa", level: 3}, {label: "Small Sofa Wooden", key: "smallSofaWooden", level: 3}]}, {label: "Games", key: "games", level: 2, children: []}]}, {label: "Refurbrished Items", key: "refurbrished items", level: 1, children: []}, {label: "Indoor", key: "indoor", level: 1, children: [{label: "Electicity", key: "electicity", level: 2, children: []}, {label: "Living Room Sofa", key: "livingRoomSofa", level: 2, children: []}]}]console .log ('sofa:', filterMatches (input, {label: 'sofa'}))console .log ('furniture:', filterMatches (input, {label: 'furniture'})).as-console-wrapper {max-height: 100% !important; top: 0}我们分离出递归过滤机制以及对象匹配部分,将它们重新放在一起filterMatches。这个想法是,我们可能想通过多种方式进行过滤,因此该函数采用可以测试当前节点的任意谓词函数。testIncludes接受一个键值对对象并返回一个函数,该函数接受一个对象并报告该对象的相应键是否均包含相关值。(我根据您的输入/请求的输出组合在此处添加了不区分大小写的检查。)请注意,我用单词filter而不是 来命名中心函数find,因为find通常意味着返回第一个匹配项,而filter应该返回所有匹配项。为了我自己的使用,我会稍微不同地构造 main 函数:const filterMatches = (conditions) => (obj) =>  filterDeep (testIncludes (conditions)) (obj)console .log ('sofa:', filterMatches ({label: 'sofa'}) (input))我非常喜欢这些柯里化函数,并且按照这个顺序的参数,我觉得它们是最有用的。但是YMMV。更新评论指出主要功能出现 lint 故障。这是可以理解的,因为这在条件表达式内使用赋值时做了一些棘手的事情。所以这里有一些工作变体:将分配移至默认参数:const filterDeep = (pred) => (xs, kids) =>  xs .flatMap (    (x, _, __, kids = filterDeep (pred) (x .children || [])) =>       pred (x)        ? [x]      : kids.length        ? [{... x, children: kids}]       : []   )优点:这使我们的仅表达风格保持活力,并避免了上述的棘手问题。很容易阅读缺点:它使用默认参数,这有其问题。flatMat它需要从(Here_和__.)中命名两个未使用的参数使用声明样式:const filterDeep = (pred) => (xs, kids) =>  xs .flatMap ((x) => {    if (pred (x)) {      return [x]    }    const kids = filterDeep (pred) (x .children || [])    if (kids.length > 0) {      return [{... x, children: kids}]     }    return []  })优点:不再有任何形式的棘手更适合初学者缺点:if与使用纯表达式相比, and returnare语句和语句导致的模块化代码较少。使用call辅助函数:const call = (fn, ...args) => fn (...args)const filterDeep = (pred) => (xs, kids) =>  xs .flatMap (    (x) =>       pred (x)        ? [x]      : call (        (kids) => kids.length ? [{... x, children: kids}] : [],         filterDeep (pred) (x .children || [])      )  )优点:辅助函数call非常有用,并且可以在很多地方重用。它避免了任何参数的摆弄缺点:这将真正的三部分测试(returning [x]、returning[{... x, children: kids}]和returning [])的最后两个子句合并到一个函数中我对最后一个版本有一点偏好。但他们中的任何一个都可以。

慕姐8265434

也许这就足够了:const findTerm = (arr, term) => arr.filter(e => JSON.stringify(e).indexOf(term) >= 0)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript