agm*_*984 10 javascript arrays search filtering
我在这里有这个示例代码,我试图过滤匹配的对象,而不会增加代码的复杂性或性能:
此处的代码根据一个明确定义的键过滤匹配项,并且不区分大小写。
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)Run Code Online (Sandbox Code Playgroud)
目标:
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' },
Run Code Online (Sandbox Code Playgroud)
我已经搜索了与 相关的文档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)
Run Code Online (Sandbox Code Playgroud)
[编辑]这绝对有效,但可以接受吗?
// 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' },
Run Code Online (Sandbox Code Playgroud)
内存占用优化:
const found = people.filter((person) => JSON.stringify(person)
.toLowerCase()
.indexOf(searchString.toLowerCase()) !== -1
)
Run Code Online (Sandbox Code Playgroud)
转换为函数:
const fuzzyMatch = (collection, searchTerm) =>
collection.filter((obj) => JSON.stringify(obj)
.toLowerCase()
.indexOf(searchTerm.toLowerCase()) !== -1
)
console.log(fuzzyMatch(people, 'bob'))
Run Code Online (Sandbox Code Playgroud)
这里有一些很好的答案;到目前为止,我选择了这个来满足我的过滤需求:
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)
Run Code Online (Sandbox Code Playgroud)
我使它能够支持区分大小写并排除特定键。
如果我们假设所有的属性都是字符串,那么你可以通过以下方式进行
const people = [
// ...
]
const searchString = 'Bob'
const filterBy = (term) => {
const termLowerCase = term.toLowerCase()
return (person) =>
Object.keys(person)
.some(prop => person[prop].toLowerCase().indexOf(termLowerCase) !== -1)
}
const found = people.filter(filterBy(searchString))
console.log(found)
Run Code Online (Sandbox Code Playgroud)
更新:使用 RegExp 和更老派的替代解决方案 :) 但快 2 倍
const people = [
// ...
]
const searchString = 'Bob'
const escapeRegExp = (str) => // or better use 'escape-string-regexp' package
str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
const filterBy = (term) => {
const re = new RegExp(escapeRegExp(term), 'i')
return person => {
for (let prop in person) {
if (!person.hasOwnProperty(prop)) {
continue;
}
if (re.test(person[prop])) {
return true;
}
}
return false;
}
}
const found = people.filter(filterBy(searchString))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8104 次 |
| 最近记录: |