Simple Fuzzy Search

Hi everyone!
I’ve noticed that there isn’t a fuzzy search resource available on the forums yet so I created a basic implementation by using the longest common subsequence algorithm. (If there is one available please link it below).

What is fuzzy search?
Fuzzy search is a way to search strings based on how approximate the strings match. It is similar to a google search. If you miss a character or two in a google search, it would still give you results that approximate to your query. My implementation is obviously a lot less sophisticated than google’s algorithm, but it gets the job done.

Current Implementation
The current implementation is to calculate the longest common subsequence between two strings and output the result based on how close the query length is to the longest common subsequence.

Usage
The module only supports 4 functions:

addItem:
The items that will be compared with the query.
Parameters: Table
The first item in the table would be the string you would receive if the fuzzy search determines that the query matches with it. The values after would be key words that would be compared with the query to determine if it matches with the first item. You could also only have one item in the table if you do not want to use keywords. Letter casing does not matter in the table.

Example:

module:addItem({"Gun", "SWAT", "shoot", "cool"})

includeItemIfOver
Parameters: Boolean
Accepts an item as a match if the query is bigger than the item but matches enough letters.
The default will be true.

Example:

module:includeItemIfOver(true);
-- query: GUNNS
-- item: gun
-- output: gun
module:includeItemIfOver(false);
-- query: GUNNS
-- item: gun
-- output:

changeAccuracy
Parameters: Integer, (1 <= integer).
How accurate the comparison between each item and query would be.
Higher value: more broad results.
Lower value: less broad results.

fuzzySearch(query, ignore white space)
parameters: string, boolean
Search through the items and returns a table of matched strings.

Usage Example:

local fuzzySearch = require(fuzzySearch) -- change it to the location of the module.
fuzzySearch:changeAccuracy(1.2) -- Higher value : more broad results. Lower Value: less broad searches. Default is set at 1.2
fuzzySearch:addItem({"Adidas Shoes", "shoe", "footwear"})
fuzzySearch:addItem({"Speed Boost", "boost", "speed", "fast"}) 
fuzzySearch:addItem({"Gun", "SWAT"}) 
fuzzySearch:includeItemIfOver(true)
local items = fuzzySearch:fuzzySearch("guns", true) -- returns a table of all matches
for _, i in pairs(items) do
	print(i)
end

Please note this is not the best implementation of a fuzzy search, there are a lot of algorithms better than the longest common subsequence that will do a better fuzzy search. Although this is not as good as other algorithms, it is still much better than exact case searches. If you have a better implementation please post it below.

You can do whatever you want with the module, crediting is not necessary.

Link: https://www.roblox.com/library/4924719443/FuzzySearch

Please comment on any bugs or issues.

34 Likes

It does not work for me.

Whenever I search for a wire, the button comes up. Only the button comes up.

local _ITEMS = {}

fuzzySearch:changeAccuracy(1.2)
for categoryname,content in pairs(Items) do
	for itemname,_ in pairs(content) do
		table.insert(_ITEMS, itemname)
	end
end

fuzzySearch:addItem(_ITEMS)
fuzzySearch:includeItemIfOver(true)


local function Search()
	ITEMS = fuzzySearch:fuzzySearch(script.Parent.Text, true)
	
	for _, i in pairs(ITEMS) do
		for _,v in pairs(script.Parent.Parent.Parent.Electronics.ScrollingFrame.Frame:GetChildren()) do
			if v:IsA("ViewportFrame") then
				if v.Name == i then
					v.Visible = true
				else
					v.Visible = false
				end
			end
		end
	end
	connection:Disconnect()
end

connection = script.Parent:GetPropertyChangedSignal("Text"):Connect(Search)

Sorry for the confusion! I think what you are trying to do right now is add a bunch of items to the fuzzySearch list. The first value in the array is the item you want returned, the values after the first item are just key words that the script compares with.
So for example:
The array you pass through: {“Gun”, “Swat”, “Damage”, “GamePass”}
The item returned in this case will always be “Gun” and the items after are just key words that the script compares. So if a player searches “GamePass”, “Gun” would be returned since it finds the keyword under “Gun”.
In your case to add all your items you would have to keep doing fuzzySearch:AddItem to each item.

Like This:
fuzzySearch:addItem(_ITEMS[index])

1 Like