--!native --!optimize 2 -- Compiled with roblox-ts v3.0.0 local TS = _G[script] local CharAt = TS.import(script, script.Parent.Parent, "Utils", "CharAt") local function JaroDistance(string_1, string_2, case_sensitive) if case_sensitive == nil then case_sensitive = true end if #string_1 == 0 or #string_2 == 0 then return 0 end if not case_sensitive then string_1 = string.upper(string_1) string_2 = string.upper(string_2) end if string_1 == string_2 then return 1 end local m = 0 local len1 = #string_1 local len2 = #string_1 local window = math.floor(math.max(len1, len2) / 2) - 1 local str1_hash = table.create(len1) local str2_hash = table.create(len2) for i = 0, len1 - 1 do for j = math.max(0, i - window), math.min(len2, i + window + 1) - 1 do if not str1_hash[i + 1] and not str2_hash[j + 1] and CharAt(string_1, i) == CharAt(string_2, j) then m += 1 local _index = j + 1 str2_hash[_index] = true str1_hash[i + 1] = str2_hash[_index] break end end end if m == 0 then return 0 end local t = 0 local point = 0 for i = 0, len1 - 1 do if str1_hash[i + 1] then while not str2_hash[point + 1] do point += 1 end local _exp = CharAt(string_1, i) local _exp_1 = string_2 local _original = point point += 1 if _exp ~= CharAt(_exp_1, _original) then t += 1 end end end t /= 2 return (m / len1 + m / len2 + (m - t) / m) / 3 end --*@see https://github.com/kwunshing123/jaro-winkler-typescript/blob/master/src/index.ts local function JaroWinklerScore(term, query, case_sensitive) if case_sensitive == nil then case_sensitive = true end local jaro_dist = JaroDistance(term, query, case_sensitive) local prefix = 0 if jaro_dist > 0.7 then local min_index = math.min(#term, #query) local i = 0 while CharAt(term, i) == CharAt(query, i) and i < 4 and i < min_index do prefix += 1 i += 1 end jaro_dist += 0.1 * prefix * (1 - jaro_dist) end return jaro_dist end return { JaroWinklerScore = JaroWinklerScore, }