快速、轻量且出色的 JavaScript 模糊搜索工具。
快速:搜索 13,000 个文件仅需 不到1毫秒。
轻量: 单文件,零依赖,5KB大小。
出色:简洁的API + 结果排序优秀。
演示
https://rawgit.com/farzher/fuzzysort/master/test/test.html
安装 Node / Bun / Deno
npm i fuzzysort
import fuzzysort from 'fuzzysort'
const fuzzysort = require('fuzzysort')
浏览器安装
<script src="https://cdn.jsdelivr.net/npm/fuzzysort@3.0.2/fuzzysort.min.js"></script>
使用方法
fuzzysort.go(search, targets, options=null)
const mystuff = [{file: 'Apple.cpp'}, {file: 'Banana.cpp'}]
const results = fuzzysort.go('a', mystuff, {key: 'file'})
// [{score: 0.81, obj: {file: 'Apple.cpp'}}, {score: 0.59, obj: {file: 'Banana.cpp'}}]
选项
fuzzysort.go(search, targets, {
threshold: 0, // 不返回低于此分数的匹配结果
limit: 0, // 限制返回结果的数量
all: false, // 如果为true,空搜索时返回所有结果
key: null, // 当目标是对象时使用(参见示例用法)
keys: null, // 当目标是对象时使用(参见示例用法)
scoreFn: null, // 与`keys`一起使用(参见示例用法)
})
什么是result
const result = fuzzysort.single('query', 'some string that contains my query.')
result.score // .80 (1是完全匹配。0.5是良好匹配。0是无匹配。)
result.target // 'some string that contains my query.'
result.obj // 使用options.key时,指向原始对象的引用
result.indexes // [29, 30, 31, 32, 33]
result.highlight('<b>', '</b>')
// 'some string that contains my <b>query</b>.'
result.highlight((m, i) => <react key={i}>{m}</react>)
// ['some string that contains my ', <react key=0>query</react>, '.']
高级用法
通过多个复杂键搜索对象列表,并使用自定义权重。
let objects = [{
title: 'Liechi Berry',
meta: {desc: 'Raises Attack when HP is low.'},
tags: ['berries', 'items'],
bookmarked: true,
}, {
title: 'Petaya Berry',
meta: {desc: 'Raises Special Attack when HP is low.'},
}]
let results = fuzzysort.go('attack berry', objects, {
keys: ['title', 'meta.desc', obj => obj.tags?.join()],
scoreFn: r => r.score * r.obj.bookmarked ? 2 : 1, // 如果项目被收藏,提高其分数
})
var keysResult = results[0]
// 使用多个`keys`时,结果不同。它们可索引以获取每个普通结果
keysResult[0].highlight() // 'Liechi <b>Berry</b>'
keysResult[1].highlight() // 'Raises <b>Attack</b> when HP is low.'
keysResult.score // .84
keysResult.obj.title // 'Liechi Berry'
如何提高速度 · 性能优化技巧
let targets = [{file: 'Monitor.cpp'}, {file: 'MeshRenderer.cpp'}]
// 过滤掉不需要搜索的目标!尤其是长的目标!
targets = targets.filter(t => t.file.length < 1000)
// 如果你的目标不经常变化,请提供准备好的目标而不是原始字符串!
targets.forEach(t => t.filePrepared = fuzzysort.prepare(t.file))
// 如果你不需要引用原始对象,请不要使用 options.key
targets = targets.map(t => t.filePrepared)
const options = {
limit: 100, // 不要返回超过你需要的结果数量!
threshold: .5, // 不要返回糟糕的结果
}
fuzzysort.go('gotta', targets, options)
fuzzysort.go('go', targets, options)
fuzzysort.go('fast', targets, options)
注意事项
result.score
作为 getter/setter 实现,内部存储方式不同
r.score = .3; // r.score == 0.30000000000000004
Star 历史
更新日志
v3.0.0
- 当使用
keys
且搜索内容包含空格时,添加了新的行为! - 添加了
options.key
现在可以是一个函数{key: obj => obj.tags.join()}
- 移除了
fuzzysort.indexes
并添加了result.indexes
(作为 getter/setter 以提高 GC 性能) - 移除了
fuzzysort.highlight()
并添加了result.highlight()
- 更改评分:分数现在是从 0 到 1 的数字,而不是从负无穷到 0
- 更改评分:子字符串匹配更加相关
- 更改评分:
straw berry
现在能很好地匹配strawberry
- 更改评分:对评分进行了相当多的调整
result.score
出于性能原因使用 getter/setter- 修复了一些小问题
v2.0.0
- 当搜索内容包含空格时,添加了新的行为!
- 添加了 fuzzysort.min.js
- 现在依赖于 ES6 特性
- 移除了
result.indexes
并添加了fuzzysort.indexes
(提高了 GC 性能) - 完全移除了
options.allowTypo
- 完全移除了
fuzzysort.goAsync
- 完全移除了
fuzzysort.new
- 重写了演示
v1.9.0
- 更快的速度
- 添加了
options.all
- 弃用/移除了
options.allowTypo
- 弃用/移除了
fuzzysort.goAsync
- 更改评分:提升了子字符串匹配
- 更改评分:开始索引过多的目标因为是不好的目标而失去分数
- 更改评分:不从靠近开头处开始的惩罚
- 更改评分:更多组的惩罚
- 修复了"指数回溯导致浏览器挂起"的问题
v1.2.0
- 添加了
fuzzysort.highlight(result, callback)
v1.1.0
- 添加了
allowTypo
作为一个选项
v1.0.0
- 反转分数;现在是负数而不是正数,因此更高的分数更好
- 添加了通过
key
/keys
搜索对象的能力,可以自定义权重 - 移除了自动高亮的选项,并暴露了
fuzzysort.highlight
- 从
fuzzysort
中移除了所有选项,并将它们移到fuzzysort.go
的可选参数中
v0.x.x
- 初始化