![](/img/trans.png)
[英]Combine unknown sub-arrays of objects from an array of objects and filter it
[英]filter an arrays of objects from an array of strings
我知道有類似的問題,但到目前為止沒有人能夠幫助我 - 從字符串過濾數組和字符串數組依賴於你知道你想要匹配的鍵值對, 這里與這個問題相同
說我有一個像這樣的對象數組..
let users = [
{
name: 'Steve',
age: 42,
pets: {
dog: 'spike';
},
favouriteFood: 'apples'
},
{
name: 'Steve',
age: 32,
pets null
favouriteFood: 'icecream'
},
{
name: 'Jason',
age: 31,
pets: null
favouriteFood: 'tacos'
},
{
name: 'Jason',
age: 31,
pets: {
cat: 'Jerry'
},
favouriteFood: 'bread'
},
]
現在我希望能夠通過匹配任何對象鍵中的字符串來過濾用戶數組。 例如,我想過濾掉任何名字並非'史蒂夫'的人 - 請記住,我可能還想過濾掉任何不是42或者最喜歡的食物不是'蘋果'的人
filter(term) {
return objects.filter(x => {
for(let key of Object.keys(x)) {
if(typeof(x[key]) === 'object') {
return JSON.stringify(x[key]).toLowerCase().includes(t);
} else {
return x[key].toString().toLowerCase().includes(t);
}
}
});
}
現在這個功能可以工作,但只適用於一個過濾器術語
所以,如果我運行filter('steve')
我會得到
users = [
{
name: 'Steve',
age: 42,
pets: {
dog: 'spike';
},
favouriteFood: 'apples'
},
{
name: 'Steve',
age: 32,
pets null
favouriteFood: 'icecream'
}
]
作為我的結果,但如果我想過濾掉史蒂夫,最喜歡的食物是蘋果?
我試圖按如下方式更新我的函數以循環遍歷一個術語數組並根據數組中的所有字符串進行過濾
所以我試過了
function filter(terms) {
return term.forEach((t) => {
return objects.filter(x => {
for(let key of Object.keys(x)) {
if(typeof(x[key]) === 'object') {
return JSON.stringify(x[key]).toLowerCase().includes(t);
} else {
return x[key].toString().toLowerCase().includes(t);
}
}
});
});
但是當我運行filter(['steve', 'apples'])
我得到了undefined
我想要的結果是
users = [
{
name: 'Steve',
age: 42,
pets: {
dog: 'spike';
},
favouriteFood: 'apples'
}
]
我不完全確定我做錯了什么或如何修復此功能以使其正常工作。
任何幫助,將不勝感激。
過濾.every
值數組中的Object.values
值是否包含在給定用戶的Object.values
中:
const filter = arrOfValsNeeded => users.filter(user => { const vals = Object.values(user).map(val => typeof val === 'string' ? val.toLowerCase() : val); return arrOfValsNeeded.every(needed => vals.includes(needed.toLowerCase())); }); let users = [ { name: 'Steve', age: 42, pets: { dog: 'spike' }, favouriteFood: 'apples' }, { name: 'Steve', age: 32, pets: null, favouriteFood: 'icecream' }, { name: 'Jason', age: 31, pets: null, favouriteFood: 'tacos' }, { name: 'Jason', age: 31, pets: { cat: 'Jerry' }, favouriteFood: 'bread' }, ] console.log(filter(['steve', 'apples']));
或者,如果您需要遞歸查找所有原始值:
const allPrimitives = obj => { const primitives = []; JSON.stringify(obj, (key, val) => { if (typeof val !== 'object' || val === null) { primitives.push(typeof val === 'string' ? val.toLowerCase() : val); } return val; }); return primitives; }; const filter = arrOfValsNeeded => users.filter(user => { const vals = allPrimitives(user); return arrOfValsNeeded.every(needed => vals.includes(needed.toLowerCase())); }); let users = [ { name: 'Steve', age: 42, pets: { dog: 'spike' }, favouriteFood: 'apples' }, { name: 'Steve', age: 32, pets: null, favouriteFood: 'icecream' }, { name: 'Jason', age: 31, pets: null, favouriteFood: 'tacos' }, { name: 'Jason', age: 31, pets: { cat: 'Jerry' }, favouriteFood: 'bread' }, ] console.log(filter(['steve', 'apples']));
如果您還需要部分匹配,請使用vals.some
而不是vals.includes
以便您可以識別子字符串:
const allStrings = obj => { const strings = []; JSON.stringify(obj, (key, val) => { if (typeof val === 'string') { strings.push(val.toLowerCase()); } return val; }); return strings; }; const filter = arrOfValsNeeded => { const lowerVals = arrOfValsNeeded.map(str => str.toLowerCase()); return users.filter(user => { const existingStrings = allStrings(user); return lowerVals.every( lowerNeeded => existingStrings.some( existingString => existingString.includes(lowerNeeded) ) ); }); }; let users = [ { name: 'Steve', age: 42, pets: { dog: 'spike' }, favouriteFood: 'apples' }, { name: 'Steve', age: 32, pets: null, favouriteFood: 'icecream' }, { name: 'Jason', age: 31, pets: null, favouriteFood: 'tacos' }, { name: 'Jason', age: 31, pets: { cat: 'Jerry' }, favouriteFood: 'bread' }, ] console.log(filter(['steve', 'apples']));
回復晚了非常抱歉。 我一直試圖提出幾乎適用於任何情況的遞歸代碼。 我最終在這里找到了一些非常酷的片段,這是我從equals
派生similar
函數的地方,同時略微考慮了兼容性。
function similar(a, b){ if(a === b){ return true; } if(a instanceof Date && b instanceof Date){ return a.getTime() === b.getTime(); } if (!a || !b || (typeof a !== 'object' && typeof b !== 'object')){ return a === b; } if (a === null || a === undefined || b === null || b === undefined || a.prototype !== b.prototype){ return false; } return Object.keys(b).every(function(k){ return similar(a[k], b[k]); }); } let users = [ { name: 'Steve', age: 42, pets: { dog: 'spike' }, favouriteFood: 'apples' }, { name: 'Steve', age: 32, pets: null, favouriteFood: 'icecream' }, { name: 'Jason', age: 31, pets: null, favouriteFood: 'tacos' }, { name: 'Jason', age: 31, pets: { cat: 'Jerry' }, favouriteFood: 'bread' } ] var testObj = {name:'Jason', age: 31, pets:{cat:'Jerry'}}; for(var i=0,u,l=users.length; i<l; i++){ u = users[i]; if(similar(u, testObj)){ console.log('contains testObj'); console.log(u); } else if(!similar(u, {pets:null}) && !similar(u, {pets:{dog:'spot'}})){ console.log('not spot'); console.log(u); } }
similar
將看到是否有任何匹配的東西不是一個對象,或者如果它是一個對象,它將看到a
包含b
,考慮到a
和b
在同一深度具有屬性和值而b
不包含屬性在不存在的a
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.