Update SAYT algo to give better matches
The algorithm will now give higher rankings to items containing multiple sequential letters which match, and higher rankings to those whose length more closely matches the given term.
This commit is contained in:
@@ -47,25 +47,36 @@ module.exports = class ItemSelector extends BaseModel
|
|||||||
|
|
||||||
# Private Methods ##############################################################################
|
# Private Methods ##############################################################################
|
||||||
|
|
||||||
_isMatch: (name, itemSlug)->
|
_computeScore: (name, itemSlug)->
|
||||||
hintIndex = 0
|
hintIndex = 0
|
||||||
hintLetter = @_hint[hintIndex]
|
hintLetter = @_hint[hintIndex]
|
||||||
name = name.toLowerCase()
|
name = name.toLowerCase()
|
||||||
|
nextScore = 1
|
||||||
|
totalScore = 0
|
||||||
|
|
||||||
for nameIndex in [0...name.length] by 1
|
for nameIndex in [0...name.length] by 1
|
||||||
if name.charAt(nameIndex) is hintLetter
|
if name.charAt(nameIndex) is hintLetter
|
||||||
|
totalScore += nextScore
|
||||||
|
nextScore += 1
|
||||||
hintIndex += 1
|
hintIndex += 1
|
||||||
if hintIndex is @_hint.length
|
if hintIndex is @_hint.length
|
||||||
item = @_modPack.findItem itemSlug
|
item = @_modPack.findItem itemSlug
|
||||||
return false unless item?
|
return 0 unless item?
|
||||||
return @_isAcceptable item
|
return 0 unless @_isAcceptable item
|
||||||
hintLetter = @_hint[hintIndex]
|
break
|
||||||
|
|
||||||
return false
|
hintLetter = @_hint[hintIndex]
|
||||||
|
else
|
||||||
|
nextScore = 1
|
||||||
|
|
||||||
|
return 0 if hintIndex < @_hint.length
|
||||||
|
|
||||||
|
totalScore *= @_hint.length / name.length
|
||||||
|
return totalScore
|
||||||
|
|
||||||
_refreshResults: ->
|
_refreshResults: ->
|
||||||
oldResults = @_results
|
oldResults = @_results
|
||||||
newResults = {}
|
scoredItems = []
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
logger.verbose => "Looking for items which match: #{@_hint}"
|
logger.verbose => "Looking for items which match: #{@_hint}"
|
||||||
@@ -75,15 +86,18 @@ module.exports = class ItemSelector extends BaseModel
|
|||||||
return unless mod.enabled
|
return unless mod.enabled
|
||||||
|
|
||||||
mod.eachName (name, itemSlug)=>
|
mod.eachName (name, itemSlug)=>
|
||||||
return if count >= @_maxResults
|
return if scoredItems.length >= @_maxResults
|
||||||
|
return unless itemSlug.isQualified
|
||||||
|
|
||||||
if @_isMatch name, itemSlug
|
score = @_computeScore name, itemSlug
|
||||||
if itemSlug.isQualified
|
if score >= @_hint.length
|
||||||
newResults[itemSlug] = itemSlug
|
scoredItems.push score:score, itemSlug:itemSlug
|
||||||
count += 1
|
|
||||||
|
|
||||||
newResults = _.values(newResults)
|
scoredItems.sort (a, b)->
|
||||||
newResults.sort ItemSlug.compare
|
if a.score isnt b.score
|
||||||
|
return if a.score > b.score then -1 else +1
|
||||||
|
return ItemSlug.compare a.itemSlug, b.itemSlug
|
||||||
|
|
||||||
|
newResults = (e.itemSlug for e in scoredItems)
|
||||||
@_results = newResults
|
@_results = newResults
|
||||||
@trigger c.event.change + ':results', this, oldResults, newResults
|
@trigger c.event.change + ':results', this, oldResults, newResults
|
||||||
|
|||||||
Reference in New Issue
Block a user