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:
Andrew Miner
2017-01-28 19:59:18 -08:00
parent 5d8251bebb
commit ed96cf0c71
+27 -13
View File
@@ -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