第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

如何使用 vue/javascript 通過多個屬性過濾深度嵌套的 json

如何使用 vue/javascript 通過多個屬性過濾深度嵌套的 json

慕桂英4014372 2024-01-18 15:52:17
我有一些具有以下結構的 JSON:{  "root": {    "Europe": {      "children": [        {          "name": "Germany"        },        {          "name": "England",          "children": [            {              "name": "London",              "search_words": ["city", "capital"],              "children": [                {                  "name": "Westminster",                  "search_words": ["borough"]                }              ]            },            {              "name": "Manchester",              "search_words": ["city"]            }          ]        },        {          "name": "France",          "children": [            {              "name": "Paris",              "search_words": ["city", "capital"]            }          ]        }      ]    },    "North America": {      "children": [        {          "name": "Canada",          "children": [            {              "name": "Toronto"            },            {              "name": "Ottawa"            }          ]        },        {          "name": "United States"        }      ]    }  }}我想根據(jù)文本搜索過濾 JSON。我應該能夠通過 thename和 any進行搜索search_words。最后一個問題是 JSON 可以是任意深度,因此它需要能夠搜索所有級別。我還需要循環(huán)遍歷并打印出 HTML 中的 JSON(使用 Vue),并根據(jù)搜索進行更新。目前還不清楚如何在不知道 JSON 深度的情況下執(zhí)行此操作?任何幫助將不勝感激!
查看完整描述

3 回答

?
holdtom

TA貢獻1805條經(jīng)驗 獲得超10個贊

在開始之前,我們必須首先解決輸入數(shù)據(jù)的不規(guī)則形狀 -


const data2 =

? { name:"root"

? , children:

? ? ? Array.from

? ? ? ? ( Object.entries(data.root)

? ? ? ? , ([ country, _ ]) =>

? ? ? ? ? ? Object.assign({ name:country }, _)

? ? ? ? )

? }


console.log(JSON.stringify(data2, null, 2))

現(xiàn)在我們看到的data2是一個統(tǒng)一的{ name, children: [ ... ]}形狀——


{

? "name": "root",

? "children": [

? ? {

? ? ? "name": "Europe",

? ? ? "children": [

? ? ? ? { "name": "Germany" },

? ? ? ? {

? ? ? ? ? "name": "England",

? ? ? ? ? "children": [

? ? ? ? ? ? {

? ? ? ? ? ? ? "name": "London",

? ? ? ? ? ? ? "search_words": [ "city", "capital" ],

? ? ? ? ? ? ? "children": [

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? "name": "Westminster",

? ? ? ? ? ? ? ? ? "search_words": [ "borough" ]

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ]

? ? ? ? ? ? },

? ? ? ? ? ? {

? ? ? ? ? ? ? "name": "Manchester",

? ? ? ? ? ? ? "search_words": [ "city" ]

? ? ? ? ? ? }

? ? ? ? ? ]

? ? ? ? },

? ? ? ? {

? ? ? ? ? "name": "France",

? ? ? ? ? "children": [

? ? ? ? ? ? {

? ? ? ? ? ? ? "name": "Paris",

? ? ? ? ? ? ? "search_words": [ "city", "capital" ]

? ? ? ? ? ? }

? ? ? ? ? ]

? ? ? ? }

? ? ? ]

? ? },

? ? {

? ? ? "name": "North America",

? ? ? "children": [

? ? ? ? {

? ? ? ? ? "name": "Canada",

? ? ? ? ? "children": [

? ? ? ? ? ? { "name": "Toronto" },

? ? ? ? ? ? { "name": "Ottawa" }

? ? ? ? ? ]

? ? ? ? },

? ? ? ? { "name": "United States" }

? ? ? ]

? ? }

? ]

}

現(xiàn)在我們編寫一個通用的深度優(yōu)先遍歷函數(shù),dft-


function* dft (t, path = [])

{ for (const _ of t.children ?? [])

? ? yield* dft(_, [...path, t.name ])

? yield [path, t]

}

我們的dft函數(shù)為我們的輸入樹中的path每個元素提供了一個-et


["root","Europe"]

{"name":"Germany"}


["root","Europe","England","London"]

{name:"Westminster", search_words:["borough"]}


["root","Europe","England"]

{name:"London", search_words:["city","capital"], children:[...]}


["root","Europe","England"]

{name:"Manchester", search_words:["city"]}


["root","Europe"]

{name:"England", children:[...]}


["root","Europe","France"]

{name:"Paris", search_words:["city","capital"]}


["root","Europe"]

{name:"France", children:[...]}


["root"]

{name:"Europe", children:[...]}


["root","North America","Canada"]

{name:"Toronto"}

現(xiàn)在我們知道了每個節(jié)點的路徑,我們可以創(chuàng)建一個index使用path和 anysearch_words鏈接回該節(jié)點的路徑 -


const index = t =>

? Array.from

? ? ( dft(t)

? ? , ([path, e]) =>

? ? ? ? [ [...path, e.name, ...e.search_words ?? [] ] // all words to link to e

? ? ? ? , e? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// e

? ? ? ? ]

? ? )

? ? .reduce

? ? ? ( (m, [ words, e ]) =>

? ? ? ? ? insertAll(m, words, e) // update the index using generic helper

? ? ? , new Map

? ? ? )

這取決于通用助手insertAll-


const insertAll = (m, keys, value) =>

? keys.reduce

? ? ( (m, k) =>

? ? ? ? m.set(k, [ ...m.get(k) ?? [], value ])

? ? , m

? ? )

完成后index,我們有一種方法可以為任何搜索詞創(chuàng)建快速查找 -


const myIndex =?

? index(data2)


console.log(myIndex)

Map?

{ "Europe" =>

? ? [{"name":"Germany"},{"name":"Westminster",...},{"name":"London",...},{"name":"Manchester",...},{"name":"England"...},{"name":"Manchester",...}]},{"name":"Paris",...},{"name":"France"...},{"name":"Europe"...},{"name":"Manchester",...}]},{"name":"France"...}]}]


, "Germany" =>?

? ? [{"name":"Germany"}]


, "England" =>

? ? [{"name":"Westminster",...},{"name":"London",...},{"name":"Manchester",...},{"name":"England"...},{"name":"Manchester",...}]}]


, "London" =>

? ? [{"name":"Westminster",...},{"name":"London",...}]


, "Westminster" =>

? ? [{"name":"Westminster",...}]


, "borough" =>

? ? [{"name":"Westminster",...}]


, "city" =>

? ? [{"name":"London",...},{"name":"Manchester",...},{"name":"Paris",...}]


, "capital" =>

? ? [{"name":"London",...},{"name":"Paris",...}]


, "Manchester" =>

? ? [{"name":"Manchester",...}]


, "France" =>

? ? [{"name":"Paris",...},{"name":"France"...}]


, "Paris" =>

? ? [{"name":"Paris",...}]


, "North America" =>

? ? [{"name":"Toronto"},{"name":"Ottawa"},{"name":"Canada"...},{"name":"United States"},{"name":"North America"...},

? ? {"name":"United States"}]}]


, "Canada" =>

? ? [{"name":"Toronto"},{"name":"Ottawa"},{"name":"Canada"...}]


, "Toronto" =>

? ? [{"name":"Toronto"}]


, "Ottawa" =>

? ? [{"name":"Ottawa"}]


, "United States" =>

? ? [{"name":"United States"}]? ?

}

這應該突出顯示數(shù)據(jù)中剩余的不一致之處。例如,您有一些嵌套在city、capital或下的節(jié)點borough。另外值得注意的是,我們可能應該使用s.toLowerCase()所有索引鍵,以便查找不區(qū)分大小寫。這是留給讀者的練習。


創(chuàng)建index很容易,您只需要做一次-


const myIndex =?

? index(data2)

您的索引可以根據(jù)需要重復用于任意多次查找 -


console.log(myIndex.get("Toronto") ?? [])

console.log(myIndex.get("France") ?? [])

console.log(myIndex.get("Paris") ?? [])

console.log(myIndex.get("Canada") ?? [])

console.log(myIndex.get("Zorp") ?? [])

[{"name":"Toronto"}]

[{"name":"Paris",...},{"name":"France"...}]

[{"name":"Paris",...}]

[{"name":"Toronto"},{"name":"Ottawa"},{"name":"Canada"...}]

[]

將結果插入 Vue 應用程序由您完成。


查看完整回答
反對 回復 2024-01-18
?
江戶川亂折騰

TA貢獻1851條經(jīng)驗 獲得超5個贊

不完全清楚您要從問題中尋找什么,但我猜您需要修改數(shù)據(jù)以確保在渲染時正確突出顯示匹配的數(shù)據(jù)?

這是使用對象掃描查找匹配對象的解決方案

// const objectScan = require('object-scan');


const myData = { root: { Europe: { children: [{ name: 'Germany' }, { name: 'England', children: [{ name: 'London', search_words: ['city', 'capital'], children: [{ name: 'Westminster', search_words: ['borough'] }] }, { name: 'Manchester', search_words: ['city'] }] }, { name: 'France', children: [{ name: 'Paris', search_words: ['city', 'capital'] }] }] }, 'North America': { children: [{ name: 'Canada', children: [{ name: 'Toronto' }, { name: 'Ottawa' }] }, { name: 'United States' }] } } };

// eslint-disable-next-line camelcase

const mySearchFn = (term) => ({ name, search_words = [] }) => name === term || search_words.includes(term);


const search = (input, searchFn) => objectScan(['**[*]'], {

? filterFn: ({ value, context }) => {

? ? if (searchFn(value)) {

? ? ? const { children, ...match } = value;

? ? ? context.push(match);

? ? }

? }

})(input, []);


console.log(search(myData, mySearchFn('Toronto')));

// => [ { name: 'Toronto' } ]

console.log(search(myData, mySearchFn('borough')));

// => [ { name: 'Westminster', search_words: [ 'borough' ] } ]

console.log(search(myData, mySearchFn('capital')));

// => [ { name: 'Paris', search_words: [ 'city', 'capital' ] }, { name: 'London', search_words: [ 'city', 'capital' ] } ]

.as-console-wrapper {max-height: 100% !important; top: 0}

<script src="https://bundle.run/object-scan@13.8.0"></script>


這就是您如何注入信息,然后渲染管道可以獲取這些信息

// const objectScan = require('object-scan');


const myData = { root: { Europe: { children: [{ name: 'Germany' }, { name: 'England', children: [{ name: 'London', search_words: ['city', 'capital'], children: [{ name: 'Westminster', search_words: ['borough'] }] }, { name: 'Manchester', search_words: ['city'] }] }, { name: 'France', children: [{ name: 'Paris', search_words: ['city', 'capital'] }] }] }, 'North America': { children: [{ name: 'Canada', children: [{ name: 'Toronto' }, { name: 'Ottawa' }] }, { name: 'United States' }] } } };

// eslint-disable-next-line camelcase

const mySearchFn = (term) => ({ name, search_words = [] }) => name === term || search_words.includes(term);


const search = (input, searchFn) => objectScan(['**[*]'], {

? filterFn: ({ value }) => {

? ? if (searchFn(value)) {

? ? ? value.css = { highlight: true };

? ? ? return true;

? ? } else {

? ? ? delete value.css;

? ? ? return false;

? ? }

? },

? rtn: 'count' // return number of matches

})(input);


console.log(search(myData, mySearchFn('Toronto')));

// => 1

console.log(myData);

// => { root: { Europe: { children: [ { name: 'Germany' }, { name: 'England', children: [ { name: 'London', search_words: [ 'city', 'capital' ], children: [ { name: 'Westminster', search_words: [ 'borough' ] } ] }, { name: 'Manchester', search_words: [ 'city' ] } ] }, { name: 'France', children: [ { name: 'Paris', search_words: [ 'city', 'capital' ] } ] } ] }, 'North America': { children: [ { name: 'Canada', children: [ { name: 'Toronto', css: { highlight: true } }, { name: 'Ottawa' } ] }, { name: 'United States' } ] } } }


console.log(search(myData, mySearchFn('borough')));

// => 1

console.log(myData);

// => { root: { Europe: { children: [ { name: 'Germany' }, { name: 'England', children: [ { name: 'London', search_words: [ 'city', 'capital' ], children: [ { name: 'Westminster', search_words: [ 'borough' ], css: { highlight: true } } ] }, { name: 'Manchester', search_words: [ 'city' ] } ] }, { name: 'France', children: [ { name: 'Paris', search_words: [ 'city', 'capital' ] } ] } ] }, 'North America': { children: [ { name: 'Canada', children: [ { name: 'Toronto' }, { name: 'Ottawa' } ] }, { name: 'United States' } ] } } }


console.log(search(myData, mySearchFn('capital')));

// => 2

console.log(myData);

// => { root: { Europe: { children: [ { name: 'Germany' }, { name: 'England', children: [ { name: 'London', search_words: [ 'city', 'capital' ], children: [ { name: 'Westminster', search_words: [ 'borough' ] } ], css: { highlight: true } }, { name: 'Manchester', search_words: [ 'city' ] } ] }, { name: 'France', children: [ { name: 'Paris', search_words: [ 'city', 'capital' ], css: { highlight: true } } ] } ] }, 'North America': { children: [ { name: 'Canada', children: [ { name: 'Toronto' }, { name: 'Ottawa' } ] }, { name: 'United States' } ] } } }

.as-console-wrapper {max-height: 100% !important; top: 0}

<script src="https://bundle.run/object-scan@13.8.0"></script>


使用庫對你來說可能不值得,這是一種權衡。如果您對此答案有疑問/想法,請告訴我。


查看完整回答
反對 回復 2024-01-18
?
慕尼黑的夜晚無繁華

TA貢獻1864條經(jīng)驗 獲得超6個贊

正如謝謝指出的那樣,不一致的數(shù)據(jù)格式使得為此編寫好的代碼變得更加困難。我的方法略有不同。我沒有轉換數(shù)據(jù),而是為通用函數(shù)編寫了一個包裝器,以便以更有用的方式處理此輸出。


我們從一個函數(shù)開始collect,它將遞歸地處理{name?, search_words?, children?, ...rest}對象,返回與給定謂詞匹配的節(jié)點并在子節(jié)點上重復出現(xiàn)。我們用函數(shù) 來調用它,search它接受一個搜索詞并從中創(chuàng)建一個謂詞。(這里我們測試是否name或任何search_term匹配該術語;對于部分匹配、不區(qū)分大小寫等,這很容易修改。)


然后我們編寫我提到的包裝器searchLocations。它下降到節(jié)點,然后映射并組合調用每個根值.root的結果。search


const collect = (pred) => ({children = [], ...rest}) => [

  ... (pred (rest) ? [rest] : []),

  ... children .flatMap (collect (pred))

]

  

const search = (term) => 

  collect (({name = '', search_words = []}) => name == term || search_words .includes (term))


const searchLocations = (locations, term) => 

  Object.values (locations .root) .flatMap (search (term))


const locations = {root: {Europe: {children: [{name: "Germany"}, {name: "England", children: [{name: "London", search_words: ["city", "capital"], children: [{name: "Westminster", search_words: ["borough"]}]}, {name: "Manchester", search_words: ["city"]}]}, {name: "France", children: [{name: "Paris", search_words: ["city", "capital"]}]}]}, "North America": {children: [{name: "Canada", children: [{name: "Toronto"}, {name: "Ottawa"}]}, {name: "United States"}]}}}


console .log ('Toronto', searchLocations (locations, 'Toronto'))

console .log ('borough', searchLocations (locations, 'borough'))

console .log ('capital', searchLocations (locations, 'capital'))

.as-console-wrapper {max-height: 100% !important; top: 0}

如果您想要的(聽起來像是您可能想要的)與輸入的結構相同,僅保留包含匹配項所需的節(jié)點,那么我們應該能夠從樹過濾函數(shù)開始執(zhí)行類似的操作。假期后我會嘗試看看。


更新

我確實又看了一遍,希望將樹作為一棵樹來過濾。代碼并沒有那么難。但這一次,我確實使用了一個convert函數(shù)將您的數(shù)據(jù)轉換為更一致的遞歸結構。因此,整個對象變成一個數(shù)組,根部有兩個元素,一個元素為name“歐洲”,另一個元素為name“北美”,每個元素都有其現(xiàn)有children節(jié)點。這使得所有進一步的處理變得更加容易。


這里有兩個關鍵函數(shù):


第一個是通用deepFilter函數(shù),它采用謂詞和項目數(shù)組,這些項目的節(jié)點children結構可能類似于其父級,并返回一個新版本,其中包含與謂詞及其完整祖先匹配的任何內容。它看起來像這樣:


const deepFilter = (pred) => (xs) =>

  xs .flatMap (({children = [], ...rest}, _, __, kids = deepFilter (pred) (children)) =>

    pred (rest) || kids.length

      ? [{...rest, ...(kids.length ? {children: kids} : {})}]

      : []

  )

第二個是專門針對這個問題的:searchLocation。它調用deepFilter使用由搜索項和已討論的轉換結構構造的謂詞。它使用convert結構的幫助器,以及search將搜索詞轉換為謂詞的幫助器,該謂詞在名稱和所有搜索詞上查找(不區(qū)分大小寫)部分匹配。


const searchLocations = (loc, locations = convert(loc)) => (term) =>

  term.length ? deepFilter (search (term)) (locations) : locations

這通過用戶界面來演示,該用戶界面顯示嵌套中的位置<UL>,并帶有實時過濾位置的搜索框。


例如,如果您在搜索框中輸入“w”,您將得到


Europe

  England

    London (city, capital)

      Westminster (borough)

North America

  Canada

    Ottawa

因為“Westminster”和“Ottawa”是唯一的匹配項。


如果你輸入“城市”你會得到


Europe

  England

    London (city, capital)

    Manchester (city)

  France

    Paris (city, capital)

您可以在此代碼片段中看到它的實際效果:


// utility function

const deepFilter = (pred) => (xs) =>

  xs .flatMap (({children = [], ...rest}, _, __, kids = deepFilter (pred) (children)) =>

    pred (rest) || kids.length

      ? [{...rest, ...(kids.length ? {children: kids} : {})}]

      : []

  )


// helper functions

const search = (t = '', term = t.toLowerCase()) => ({name = '', search_words = []}) =>

  term.length &&  (

    name .toLowerCase () .includes (term) ||

    search_words .some (word => word .toLowerCase() .includes (term))

  )


const convert = ({root}) => 

  Object.entries (root) .map (([name, v]) => ({name, ...v}))



// main function

const searchLocations = (loc, locations = convert(loc)) => (term) =>

  term.length ? deepFilter (search (term)) (locations) : locations



// sample data

const myData = { root: { Europe: { children: [{ name: 'Germany' }, { name: 'England', children: [{ name: 'London', search_words: ['city', 'capital'], children: [{ name: 'Westminster', search_words: ['borough'] }] }, { name: 'Manchester', search_words: ['city'] }] }, { name: 'France', children: [{ name: 'Paris', search_words: ['city', 'capital'] }] }] }, 'North America': { children: [{ name: 'Canada', children: [{ name: 'Toronto' }, { name: 'Ottawa' }] }, { name: 'United States' }] } } };



// main function specialized to given data

const mySearch = searchLocations(myData)



// UI demo

const format = (locations, searchTerm) => `<ul>${

  locations.map(loc => `<li>${

    loc.name + 

    (loc.search_words ? ` (${loc.search_words. join(', ')})` : ``) + 

    (loc.children ? format(loc.children, searchTerm) : '')

  }</li>`)

  .join('') 

}</ul>`


const render = (locations, searchTerm) => 

  document .getElementById ('main') .innerHTML = format (locations, searchTerm)


document .getElementById ('search') .addEventListener (

  'keyup',

  (e) => render (mySearch (e.target.value))

)


// show demo

render (mySearch (''))

<div style="float: right" id="control">

  <label>Search: <input type="text" id="search"/></label>

</div>

<div style="margin-top: -1em" id="main"></div>


顯然,這并沒有使用Vue來生成樹,只是進行一些字符串操作和innerHTML. 我把這部分留給你。但它應該顯示另一種過濾嵌套結構的方法。


查看完整回答
反對 回復 2024-01-18
  • 3 回答
  • 0 關注
  • 265 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號