我有以下物件陣列;但是,這可能是任何未知的鍵/值并且可以無限嵌套,現在這是一個測驗示例:
[
{
"reference_id": "R123",
"customer": "Person 1",
"customer_email": "[email protected]",
"location": "UK",
"bookings": [
{
"product": "Product 1",
"provider": "Company 1",
"cancellable": true
},
{
"product": "Product 2",
"provider": "Company 2",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
},
{
"reference_id": "R1234",
"customer": "Person 2",
"customer_email": "[email protected]",
"location": "USA",
"bookings": [
{
"product": "Product 1",
"provider": "Company 1",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
},
{
"reference_id": "R12345",
"customer": "Person 3",
"customer_email": "[email protected]",
"location": "UK",
"bookings": [
{
"product": "Product 2",
"provider": "Company 2",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
}
]
我目前的實作如下:
const selected = [
{
term: 'Company 1',
column: 'provider',
},
{
term: 'Person 1',
column: 'customer',
},
];
const recursivelyFilterByValue = () => (value) => selected.every((item) => {
if (!value) return false;
if (typeof value === 'string') {
// console.log('value', value === item.term);
return value === item.term;
}
if (Array.isArray(value)) {
return value.some(this.recursivelyFilterByValue());
}
if (typeof value === 'object') {
return Object.values(value).some(this.recursivelyFilterByValue());
}
return false;
});
const results = data.filter(recursivelyFilterByValue());
基本上,我將添加到“選定”陣列中,然后使用它來過濾資料陣列。我確實想確保密鑰與“列”匹配,但我還沒有添加。
對于上面的輸入,我希望輸出以下內容:
[
{
"reference_id": "R123",
"customer": "Person 1",
"customer_email": "[email protected]",
"location": "UK",
"bookings": [
{
"product": "Product 1",
"provider": "Company 1",
"cancellable": true
},
{
"product": "Product 2",
"provider": "Company 2",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
},
]
但是輸出陣列是空的。如果我只搜索一個術語(從所選陣列中洗掉除一個術語之外的所有術語),則該術語的輸出是正確的,但是任何后續術語都會回傳一個空白陣列。
我想知道我對 .some() 的使用是否是問題,但是改變它會導致太多的遞回錯誤。
Essentially, I want to return the original parent object so long as there is a key:value match for all my conditions in the selected array, at any level of its children.
Any guidance would be much appreciated, thank you.
uj5u.com熱心網友回復:
我不太確定這是否是你要找的。它假設我在評論中的猜測是正確的:
我有這個權利嗎?您有一個(可能是動態的)條件,表明一個物件要么具有
provider具有值的屬性,要么具有具有值"Customer 1"的(遞回)后代物件。并且您有關于customerand的第二個條件"Person 1",并且您正在尋找同時滿足兩個(或所有)這些條件的物件。這是否描述了您正在嘗試做的事情?
這里我們有兩個相當簡單的輔助函式,testRecursive以及makePredicates主函式recursivelyFilterByValue:
const testRecursive = (pred) => (obj) =>
pred (obj) || Object (obj) === obj && Object .values (obj) .some (testRecursive (pred))
const makePredicates = (criteria) =>
criteria .map (({term, column}) => (v) => v [column] == term)
const recursivelyFilterByValue = (criteria, preds = makePredicates (criteria)) => (xs) =>
xs .filter (obj => preds .every (pred => testRecursive (pred) (obj)))
const selected = [{term: 'Company 1', column: 'provider'}, {term: 'Person 1', column: 'customer'}]
const input = [{reference_id: "R123", customer: "Person 1", customer_email: "[email protected]", location: "UK", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R1234", customer: "Person 2", customer_email: "[email protected]", location: "USA", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R12345", customer: "Person 3", customer_email: "[email protected]", location: "UK", bookings: [{product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}]
console .log (recursivelyFilterByValue (selected) (input))
.as-console-wrapper {max-height: 100% !important; top: 0}
testRecursive檢查謂詞對于物件或嵌套在其中的任何物件是否為真。makePredicates將 -objects陣列{term, column}轉換為謂詞函式,用于測驗物件在列命名的屬性中是否具有適當的術語。recursivelyFilterByValue結合這些,呼叫makePredicates將所選專案轉換為謂詞函式,然后通過測驗每個謂詞是否為真來過濾輸入。
這不是可以想象的最有效的代碼。它重新掃描每個謂詞的層次結構。我相信我們可以找出一個版本來只進行一次掃描,但我認為它會產生更復雜的代碼。因此,您可能希望在生產規模的資料中測驗它是否足夠快滿足您的需求。
uj5u.com熱心網友回復:
這個解決方案不像公認的答案那么優雅,但為什么不展示我的努力。也許有人會覺得這種方式更容易理解。
const selected = [{term: 'Company 1', column: 'provider'}, {term: 'Person 1', column: 'customer'}]
const input = [{reference_id: "R123", customer: "Person 1", customer_email: "[email protected]", location: "UK", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R1234", customer: "Person 2", customer_email: "[email protected]", location: "USA", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R12345", customer: "Person 3", customer_email: "[email protected]", location: "UK", bookings: [{product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}]
const iter = (obj, sel) =>
Object.entries(obj).some(([key, value]) => {
if (Array.isArray(value))
return value.some((obj) => iter(obj, sel));
if (typeof value === 'object' && value !== null)
return iter(value, sel);
return (key === sel.column) && (value === sel.term);
});
const deepFilter = (arr, sels) =>
arr.filter((obj) =>
sels.every((sel) => iter(obj, sel)));
console.dir(deepFilter(input, selected), {depth: null});
.as-console-wrapper {max-height: 100% !important; top: 0}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/411301.html
標籤:
