commonMain.net.ormr.fuzzywuzzy.Ratio.kt Maven / Gradle / Ivy
package net.ormr.fuzzywuzzy
import net.ormr.fuzzywuzzy.diffutils.DiffUtils
import kotlin.math.round
public sealed interface Ratio : Applicable {
/**
* Applies the ratio between the two strings
*
* @param [s1] input string
* @param [s2] input string
*
* @return integer representing ratio of similarity
*/
public override fun apply(s1: String, s2: String): Int
/**
* Applies the ratio between the two strings
*
* @param [s1] Input string
* @param [s2] Input string
* @param [toString] string processor to pre-process strings before calculating the ratio
*
* @return integer representing ratio of similarity
*/
public fun apply(s1: String, s2: String, toString: ToStringFunction): Int
/**
* Partial ratio of similarity.
*/
public data object Partial : Ratio {
/**
* Returns a partial ratio between [s1] and [s2].
*/
public override fun apply(s1: String, s2: String): Int {
val shorter: String
val longer: String
if (s1.length <= s2.length) {
shorter = s1
longer = s2
} else {
shorter = s2
longer = s1
}
val blocks = DiffUtils.getMatchingBlocks(shorter, longer)
val scores = mutableListOf()
for (block in blocks) {
val dist: Int = block.dpos - block.spos
val longStart = if (dist > 0) dist else 0
var longEnd = longStart + shorter.length
if (longEnd > longer.length) longEnd = longer.length
val longSubstring = longer.substring(longStart, longEnd)
val ratio: Double = DiffUtils.getRatio(shorter, longSubstring)
if (ratio > .995) {
return 100
} else {
scores.add(ratio)
}
}
return round(100 * scores.max()).toInt()
}
public override fun apply(
s1: String,
s2: String,
toString: ToStringFunction,
): Int = apply(toString(s1), toString(s2))
}
public data object Simple : Ratio {
/**
* Returns a Levenshtein distance ratio between [s1] and [s2].
*/
public override fun apply(s1: String, s2: String): Int = round(100 * DiffUtils.getRatio(s1, s2)).toInt()
public override fun apply(
s1: String,
s2: String,
toString: ToStringFunction,
): Int = apply(toString(s1), toString(s2))
}
}