物管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

196 lines
5.1 KiB

let allPinyin = []
let notone = {};
let storage = {}
function init(dict) {
// https://github.com/xmflswood/pinyin-match/issues/37
const handledDict = {}
const uv = ['ju','jun','jue','juan','qu','qun','que','xuan','xu','xue','yu','yuan','yue','yun','nve','lve']
// https://github.com/xmflswood/pinyin-match/pull/43
const vList = ['lv', 'lve', 'nv', 'nve']
Object.keys(dict).forEach(key => {
handledDict[key] = dict[key]
allPinyin.push(key)
if (uv.includes(key)) {
const replacedKey = replaceUv(key)
handledDict[replacedKey] = dict[key]
allPinyin.push(replacedKey)
}
if (vList.includes(key)) {
const replacedKey = key.replace('v', 'ü')
handledDict[replacedKey] = dict[key]
allPinyin.push(replacedKey)
}
})
notone = parseDict(handledDict)
return match
}
function replaceUv(str) {
if (str.indexOf('u') !== -1) return str.replace('u', 'v')
return str.replace('v', 'u')
}
function parseDict(dict) {
let parseDict = {}
for (let i in dict) {
let temp = dict[i]
for (let j = 0, len = temp.length; j < len; j++) {
if (!parseDict[temp[j]]) {
parseDict[temp[j]] = i
} else {
parseDict[temp[j]] = parseDict[temp[j]] + ' ' + i
}
}
}
return parseDict
}
function getPinyin(cn) {
let result = []
for (let i = 0, len = cn.length; i < len; i++) {
let temp = cn.charAt(i)
result.push(notone[temp] || temp)
}
return result
}
// 对输入拼音进行切分
function wordBreak(s) {
let result = []
let solutions = []
let len = s.length
let possible = []
for (let i = 0; i <= len; i++) {
possible.push(true)
}
getAllSolutions(0, s, result, solutions, possible)
return solutions
}
function getAllSolutions(start, s, result, solutions, possible) {
let len = s.length
if (start === len) {
solutions.push(result.join(' '))
return
}
for (let i = start; i < len; i++) {
let piece = s.substring(start, i + 1)
let match = false
// 最后一个音特殊处理,不需要全部打完整
if (allPinyin.some(i => i.indexOf(piece) === 0) && !s[i + 1] && possible[i + 1]) {
if (piece.length === 1) {
result.push(piece)
} else {
let s = []
allPinyin.forEach(i => {
if (i.indexOf(piece) === 0) {
s.push(i)
}
})
result.push(s)
}
match = true
} else {
if (allPinyin.indexOf(piece) !== -1 && possible[i + 1]) {
result.push(piece)
match = true
}
}
if (match) {
let beforeChange = solutions.length
getAllSolutions(i + 1, s, result, solutions, possible)
if (solutions.length === beforeChange) {
possible[i + 1] = false
}
result.pop()
}
}
}
// 获取输入拼音的所有组合(切分 + 首字母)
function getFullKey(key) {
let result = []
wordBreak(key).forEach(i => {
let item = i.split(' ')
let last = item.length - 1
if (item[last].indexOf(',')) {
let keys = item[last].split(',')
keys.forEach(j => {
item.splice(last, 1, j)
result.push(JSON.parse(JSON.stringify(item)))
})
} else {
result.push(item)
}
})
if (result.length === 0 || (result[0].length !== key.length)) {
result.push(key.split(''))
}
// 缓存当前结果 避免重复计算
storage = {[key]: result}
return result
}
function point2point(test, key, last, extend) {
if (!test) return false
let a = test.split(' ')
a.forEach(i => {
if (i.length > 0 && extend) {
a.push(i.charAt(0))
}
})
if (!last) {
return a.indexOf(key) !== -1
}
return a.some((i) => i.indexOf(key) === 0)
}
function match(input, keys) {
if (!input || !keys) return false
input = input.toLowerCase()
keys = keys.replace(/\s+/g, '').toLowerCase()
let indexOf = input.indexOf(keys)
if (indexOf !== -1) {
return [indexOf, indexOf + keys.length - 1]
}
// 原文匹配(带空格)
let noPyIndex = getIndex(input.split(''), [keys.split('')], keys)
if (noPyIndex) return noPyIndex
// pinyin匹配
let py = getPinyin(input)
let fullString = storage[keys] || getFullKey(keys)
return getIndex(py, fullString, keys)
}
function getIndex(py, fullString, keys) {
for (let p = 0; p < py.length; p++) {
for (let k = 0; k < fullString.length; k++) {
let key = fullString[k]
let keyLength = key.length
let extend = (keyLength === keys.length)
let isMatch = true
let i = 0
let preSpaceNum = 0
let spaceNum = 0
if (keyLength <= py.length) {
for (; i < key.length; i++) {
if (i === 0 && py[p + i + preSpaceNum] === ' ') {
preSpaceNum += 1
i -= 1
} else {
if (py[p + i + spaceNum] === ' ') {
spaceNum += 1
i -= 1
} else {
if (!point2point(py[p + i + spaceNum], key[i], (py[p + i + 1] && key[i + 1]) ? false : true, extend)) {
isMatch = false
break
}
}
}
}
if (isMatch) {
return [p + preSpaceNum, spaceNum + p + i - 1]
}
}
}
}
return false
}
export default init