(candidate, query)
| 14 | }; |
| 15 | |
| 16 | export const fuzzyMatch = (candidate, query) => { |
| 17 | const lowerCandidate = (candidate || '').toLowerCase(); |
| 18 | const lowerQuery = (query || '').toLowerCase(); |
| 19 | if (!lowerQuery) return true; |
| 20 | if (lowerCandidate.includes(lowerQuery)) return true; |
| 21 | const candidateWords = lowerCandidate.split(/\s+/).filter(Boolean); |
| 22 | const queryWords = lowerQuery.split(/\s+/).filter(Boolean); |
| 23 | return queryWords.every(qw => |
| 24 | candidateWords.some(cw => { |
| 25 | const distance = levenshtein(cw, qw); |
| 26 | const threshold = Math.max(1, Math.floor(qw.length / 3)); |
| 27 | return distance <= threshold; |
| 28 | }) |
| 29 | ); |
| 30 | }; |
no test coverage detected