亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

搜索對象的嵌套數組并返回所有匹配項的完整路徑

搜索對象的嵌套數組并返回所有匹配項的完整路徑

慕蓋茨4494581 2023-07-20 10:07:54
我想搜索深度嵌套的對象數組并返回所有匹配對象的路徑。我已經部分解決了問題,但代碼僅返回第一個匹配對象的路徑。請查看輸入、預期輸出和代碼本身。我已在預期輸出部分評論了所需的邏輯。提前致謝。請幫幫我。輸入數據   [   {      "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":[               ]   },
查看完整描述

2 回答

?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

這看起來會做到這一點:


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 [])的最后兩個子句合并到一個函數中

我對最后一個版本有一點偏好。但他們中的任何一個都可以。


查看完整回答
反對 回復 2023-07-20
?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

也許這就足夠了:

const findTerm = (arr, term) => arr.filter(e => JSON.stringify(e).indexOf(term) >= 0)


查看完整回答
反對 回復 2023-07-20
  • 2 回答
  • 0 關注
  • 172 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號