我想使用遞回在嵌套物件中搜索某個鍵 OR 值,然后將該鍵 AND 值作為物件回傳。
但是,我認為我對它的理解有點錯誤,因為發現總是回傳空{}。
這是因為它被覆寫了嗎?我使用 Google 的代碼片段遍歷呼叫堆疊,可以看到正確的鍵和值被傳遞給 found,但隨后它似乎被設定回 {} 并繼續遍歷其他物件。
const test = [
{
"jack's assets": {
car: "Mercedes",
house: "6 bed mansion",
laptop: "PC",
phone: "Samsung",
watch: "Cartier",
trainers: "Adidas",
},
},
{
"mikes's assets": {
car: "Audi",
house: "4 bed detached",
laptop: "MacBook",
phone: "iPhone",
watch: "Rolex",
trainers: "Nikes",
"wifes assets": {
car: "Jeep",
laptop: "Lenovo",
phone: "Nokia",
watch: "Rotary",
trainers: "Kickers",
},
},
},
];
function dataLayerSearch(data, input) {
let found = {};
for (let obj in data) {
if (typeof data[obj] === "object") {
dataLayerSearch(data[obj], input);
} else {
if (obj === input || data[obj] === input) {
found[obj] = data[obj];
}
}
}
return found;
}
dataLayerSearch(test, "Nikes");
uj5u.com熱心網友回復:
我相信您會得到一個空物件,因為在您的示例中,您的匹配深度 > 1 層,并且您的遞回呼叫沒有將回傳值設定為任何值,因此您最初找到的變數從未被設定在頂層. 類似下面的內容會找到您的搜索詞的每個實體,并將該鍵/值作為物件插入到陣列中并回傳該陣列。
const test = [{ "jack's assets": { car: "Mercedes", house: "6 bed mansion", laptop: "PC", phone: "Samsung", watch: "Cartier", trainers: "Adidas" } }, { "mikes's assets": { car: "Audi", house: "4 bed detached", laptop: "MacBook", phone: "iPhone", watch: "Rolex", trainers: "Nikes", "wifes assets": { car: "Jeep", laptop: "Lenovo", phone: "Nokia", watch: "Rotary", trainers: "Kickers" } } }];
function dataLayerSearch(data, input) {
let found = [];
let obj = {};
for (let key in data) {
if (typeof data[key] === "object") {
found.push(...dataLayerSearch(data[key], input));
} else {
if (key === input || data[key] === input) {
obj[key] = data[key]
found.push(obj);
obj = {}
}
}
}
return found;
}
console.log(dataLayerSearch(test, "Nikes"));
console.log(dataLayerSearch(test, "laptop"));
uj5u.com熱心網友回復:
你可以早點回來找到。
順便說一句,將密鑰命名為obj具有誤導性。
function dataLayerSearch(data, input) {
const
result = [],
object = {};
let found = false;
for (const key in data) {
if (data[key] === input) {
object[key] = data[key];
if (!found) {
found = true;
result.push(object);
}
}
if (data[key] && typeof data[key] === "object") {
const temp = dataLayerSearch(data[key], input);
if (temp) result.unshift(...temp);
}
}
return result.length
? result
: undefined;
}
const test = [{ "jack's assets": { car: "Mercedes", house: "6 bed mansion", laptop: "PC", phone: "Samsung", watch: "Cartier", trainers: "Adidas", foo: "bar" } }, { "mikes's assets": { car: "Audi", house: "4 bed detached", laptop: "MacBook", phone: "iPhone", watch: "Rolex", trainers: "Nikes", "wifes assets": { car: "Jeep", laptop: "Lenovo", phone: "Nokia", watch: "Rotary", trainers: "Kickers", foo: "bar" }, foo: "bar" } }];
console.log(dataLayerSearch(test, "Nikes"));
console.log(dataLayerSearch(test, "bar"));
uj5u.com熱心網友回復:
我根本不清楚你真正想要的輸出格式是什么,但這里有一個版本會回傳如下內容:
// result of dataLayerSearch (test, 'laptop')
[
{"jack's assets": {laptop: "PC"}},
{
"mikes's assets": {
laptop: "MacBook",
"wifes assets": {laptop: "Lenovo"}
}
}
]
或這個:
// result of dataLayerSearch (test, 'Nikes')
[
{"mikes's assets": {trainers: "Nikes"}}
]
它基于我經常使用的一些功能,讓我只實作這個:
const dataLayerSearch = (xs, val) => {
const res = deepFilter (([p, v]) => v === val || p .at (-1) === val) (xs)
return Array .isArray (res) ? res .filter (Boolean) : []
}
代碼如下所示:
// utility functions
const pathEntries = (obj) =>
Object (obj) === obj
? Object .entries (obj) .flatMap (
([k, x]) => pathEntries (x) .map (([p, v]) => [[Array.isArray(obj) ? Number(k) : k, ... p], v])
)
: [[[], obj]]
const setPath = ([p, ...ps]) => (v) => (o) =>
p == undefined ? v : Object .assign (
Array .isArray (o) || Number.isInteger (p) ? [] : {},
{...o, [p]: setPath (ps) (v) ((o || {}) [p])}
)
const hydrate = (xs) =>
xs .reduce ((a, [p, v]) => setPath (p) (v) (a), {})
const deepFilter = (pred) => (o) =>
hydrate (pathEntries (o) .filter (pred))
// main function
const dataLayerSearch = (xs, val) => {
const res = deepFilter (([p, v]) => v === val || p .at (-1) === val) (xs)
return Array .isArray (res) ? res .filter (Boolean) : []
}
// sample data
const test = [{"jack's assets": {car: "Mercedes", house: "6 bed mansion", laptop: "PC", phone: "Samsung", watch: "Cartier", trainers: "Adidas", }}, {"mikes's assets": {car: "Audi", house: "4 bed detached", laptop: "MacBook", phone: "iPhone", watch: "Rolex", trainers: "Nikes", "wifes assets": {car: "Jeep", laptop: "Lenovo", phone: "Nokia", watch: "Rotary", trainers: "Kickers"}}}];
// demo
console .log (dataLayerSearch (test, 'laptop'))
console .log (dataLayerSearch (test, 'Nikes'))
.as-console-wrapper {max-height: 100% !important; top: 0}
它首先將您的輸入轉換為如下格式:
[
[[0, "jack's assets", "car"], "Mercedes"],
[[0, "jack's assets", "house"], "6 bed mansion"],
[[0, "jack's assets", "laptop"], "PC"],
[[0, "jack's assets", "phone"], "Samsung"],
[[0, "jack's assets", "watch"], "Cartier"],
[[0, "jack's assets", "trainers"], "Adidas"],
[[1, "mikes's assets", "car"], "Audi"],
[[1, "mikes's assets", "house"], "4 bed detached"],
[[1, "mikes's assets", "laptop"], "MacBook"],
[[1, "mikes's assets", "phone"], "iPhone"],
[[1, "mikes's assets", "watch"], "Rolex"],
[[1, "mikes's assets", "trainers"], "Nikes"],
[[1, "mikes's assets", "wifes assets", "car"], "Jeep"],
[[1, "mikes's assets", "wifes assets", "laptop"], "Lenovo"],
[[1, "mikes's assets", "wifes assets", "phone"], "Nokia"],
[[1, "mikes's assets", "wifes assets", "watch"], "Rotary"],
[[1, "mikes's assets", "wifes assets", "trainers"], "Kickers"]
]
我稱之為路徑輸入格式;這些記錄類似于Object .entries結果,除了不是單個鍵,我們有一個陣列來跟蹤從物件到節點的整個路徑。然后我們過濾這些以找到與您的條件匹配的那些 - 這里的值或鍵 [路徑中的最終條目] 與您的目標值匹配,但就deepFilter相關而言,它可以是任何謂詞 - 然后將它們組合回一個物件陣列。使用filter (Boolean),我們洗掉了由于 Mike 沒有任何“Nikes”鍵或值而導致的空陣列索引。我們回傳這個新陣列。isArray檢查是因為如果使用hydrate空的路徑條目串列呼叫 if,則默認情況下它回傳一個空物件。
無論如何,這可能根本不是您想要的,但它會找到您想要的資料,并為您提供更大的靈活性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/504504.html
標籤:javascript 目的 递归
