【发布时间】:2018-04-17 11:45:35
【问题描述】:
我这里有这个示例代码,我正在尝试过滤匹配的对象,而不会增加代码复杂性或性能:
这里的代码根据一个明确定义的键过滤匹配,它不区分大小写。
const people = [
{ firstName: 'Bob', lastName: 'Smith', status: 'single' },
{ firstName: 'bobby', lastName: 'Suxatcapitalizing', status: 'single' },
{ firstName: 'Jim', lastName: 'Johnson', status: 'complicated' },
{ firstName: 'Sally', lastName: 'Fields', status: 'relationship' },
{ firstName: 'Robert', lastName: 'Bobler', status: 'single' },
{ firstName: 'Johnny', lastName: 'Johannson', status: 'complicated' },
{ firstName: 'Whaley', lastName: 'McWhalerson', status: 'relationship'
rogueBonusKey: 'bob likes salmon' },
]
const searchString = 'Bob'
const found = people.filter((person) => {
if (person.firstName === searchString) return true
})
console.log(found)
目标:
- 我希望它不区分大小写
- 我希望它从任意键返回匹配项
- 我希望它使用
contains找到不完全匹配
类似这样的:
// const people = [
// { firstName: 'Bob', lastName: 'Smith', status: 'single' },
// { firstName: 'bobby', lastName: 'Suxatcapitalizing', status: 'single' },
// { firstName: 'Jim', lastName: 'Johnson', status: 'complicated' },
// { firstName: 'Sally', lastName: 'Fields', status: 'relationship' },
// { firstName: 'Robert', lastName: 'Bobler', status: 'single' },
// { firstName: 'Johnny', lastName: 'Johannson', status: 'complicated' },
// { firstName: 'Whaley', lastName: 'McWhalerson', status: 'relationship'
// rogueBonusKey: 'bob likes salmon' },
// ]
// const searchString = 'bob'
// ... magic
// console.log(found)
// { firstName: 'Bob', lastName: 'Smith', status: 'single' },
// { firstName: 'bobby', lastName: 'Suxatcapitalizing', status: 'single' },
// { firstName: 'Robert', lastName: 'Bobler', status: 'single' },
// { firstName: 'Whaley', lastName: 'McWhalerson', status: 'relationship'
// rogueBonusKey: 'bob likes salmon' },
我已经搜索了与Array.filter() 相关的文档,我绝对可以制定涉及Array.reduce() 和循环使用Object.keys(obj).forEach() 的解决方案,但我想知道是否有一种简洁、高效的方式来处理这种类型模糊搜索。
类似这样的:
const people = [
{ firstName: 'Bob', lastName: 'Smith', status: 'single' },
{ firstName: 'bobby', lastName: 'Suxatcapitalizing', status: 'single' },
{ firstName: 'Jim', lastName: 'Johnson', status: 'complicated' },
{ firstName: 'Sally', lastName: 'Fields', status: 'relationship' },
{ firstName: 'Robert', lastName: 'Bobler', status: 'single' },
{ firstName: 'Johnny', lastName: 'Johannson', status: 'complicated' },
{ firstName: 'Whaley', lastName: 'McWhalerson', status: 'relationship' },
rogueBonusKey: 'bob likes salmon' },
]
const searchString = 'Bob'
const found = people.filter((person) => {
if (person.toString().indexOf(searchString).toLowerCase !== -1) return true
})
console.log(found)
[edit]这绝对有效,但可以接受吗?
const people = [
{ firstName: 'Bob', lastName: 'Smith', status: 'single' },
{ firstName: 'bobby', lastName: 'Suxatcapitalizing', status: 'single' },
{ firstName: 'Jim', lastName: 'Johnson', status: 'complicated' },
{ firstName: 'Sally', lastName: 'Fields', status: 'relationship' },
{ firstName: 'Robert', lastName: 'Bobler', status: 'single' },
{ firstName: 'Johnny', lastName: 'Johannson', status: 'complicated' },
{ firstName: 'Whaley', lastName: 'McWhalerson', status: 'relationship',
rogueBonusKey: 'bob likes salmon' },
]
const searchString = 'Bob'
const found = people.filter((person) => {
const savageMatch = JSON.stringify(person)
.toLowerCase()
.indexOf(searchString.toLowerCase()) !== -1
console.log(savageMatch)
if (savageMatch) return true
})
console.log(found)
内存占用优化:
const found = people.filter((person) => JSON.stringify(person)
.toLowerCase()
.indexOf(searchString.toLowerCase()) !== -1
)
转换为函数:
const fuzzyMatch = (collection, searchTerm) =>
collection.filter((obj) => JSON.stringify(obj)
.toLowerCase()
.indexOf(searchTerm.toLowerCase()) !== -1
)
console.log(fuzzyMatch(people, 'bob'))
这里有一些很好的答案;到目前为止,我选择了这个来满足我的过滤需求:
const people = [
{ imageURL: 'http://www.alice.com/goat.jpeg', firstName: 'Bob', lastName: 'Smith', status: 'single' },
{ firstName: 'bobby', lastName: 'Suxatcapitalizing', status: 'single' },
{ firstName: 'Jim', lastName: 'Johnson', status: 'complicated' },
{ firstName: 'Sally', lastName: 'Fields', status: 'relationship' },
{ firstName: 'Robert', lastName: 'Bobler', status: 'single' },
{ firstName: 'Johnny', lastName: 'Johannson', status: 'complicated' },
{
firstName: 'Ronald', lastName: 'McDonlad', status: 'relationship',
rogueBonusKey: 'bob likes salmon'
},
{
imageURL: 'http://www.bob.com/cats.jpeg', firstName: 'Whaley', lastName: 'McWhalerson', status: 'relationship',
rogueBonusKey: 'bob hates salmon'
},
]
const searchString = 'bob'
const options = {
caseSensitive: false,
excludedKeys: ['imageURL', 'firstName'],
}
const customFind = (collection, term, opts) => {
const filterBy = () => {
const searchTerms = (!opts.caseSensitive) ? new RegExp(term, 'i') : new RegExp(term)
return (obj) => {
for (const key of Object.keys(obj)) {
if (searchTerms.test(obj[key]) &&
!opts.excludedKeys.includes(key)) return true
}
return false
}
}
return collection.filter(filterBy(term))
}
const found = customFind(people, searchString, options)
console.log(found)
我使它能够支持区分大小写并排除特定键。
【问题讨论】:
-
预期结果是整个匹配对象还是仅特定属性、值对?
-
匹配整个对象
标签: javascript arrays search filtering