Fixed Levenshtein distance search

Was missing lowercase transformations
This commit is contained in:
Sad Ellie 2022-09-03 13:27:30 +03:00
parent 3d9d5c6b7b
commit f8dbd7a867
2 changed files with 19 additions and 7 deletions

View File

@ -131,8 +131,8 @@ fun openLink(mContext: Context, url: String) {
* @return The amount of changes that are needed to transform one string into another * @return The amount of changes that are needed to transform one string into another
*/ */
fun String.lev(stringToCompare: String): Int { fun String.lev(stringToCompare: String): Int {
val stringA = this.lowercase() val stringA = this
val stringB = stringToCompare.lowercase() val stringB = stringToCompare
// Skipping computation for this cases // Skipping computation for this cases
if (stringA == stringB) return 0 if (stringA == stringB) return 0
@ -172,8 +172,9 @@ fun String.lev(stringToCompare: String): Int {
* @return Sorted sequence of units. Units with lower Levenshtein distance are higher * @return Sorted sequence of units. Units with lower Levenshtein distance are higher
*/ */
fun Sequence<AbstractUnit>.sortByLev(stringA: String): Sequence<AbstractUnit> { fun Sequence<AbstractUnit>.sortByLev(stringA: String): Sequence<AbstractUnit> {
val stringToCompare = stringA.lowercase()
// We don't need units where name is too different, half of the symbols is wrong in this situation // We don't need units where name is too different, half of the symbols is wrong in this situation
val threshold: Int = stringA.length / 2 val threshold: Int = stringToCompare.length / 2
// List of pair: Unit and it's levDist // List of pair: Unit and it's levDist
val unitsWithDist = mutableListOf<Pair<AbstractUnit, Int>>() val unitsWithDist = mutableListOf<Pair<AbstractUnit, Int>>()
this.forEach { unit -> this.forEach { unit ->
@ -185,12 +186,12 @@ fun Sequence<AbstractUnit>.sortByLev(stringA: String): Sequence<AbstractUnit> {
*/ */
when { when {
// It's the best possible match if it start with // It's the best possible match if it start with
unitName.startsWith(stringA) -> { unitName.startsWith(stringToCompare) -> {
unitsWithDist.add(Pair(unit, 0)) unitsWithDist.add(Pair(unit, 0))
return@forEach return@forEach
} }
// It's a little bit worse when it just contains part of the query // It's a little bit worse when it just contains part of the query
unitName.contains(stringA) -> { unitName.contains(stringToCompare) -> {
unitsWithDist.add(Pair(unit, 1)) unitsWithDist.add(Pair(unit, 1))
return@forEach return@forEach
} }
@ -210,8 +211,8 @@ fun Sequence<AbstractUnit>.sortByLev(stringA: String): Sequence<AbstractUnit> {
* With substring levDist will be 3 so unit will be included * With substring levDist will be 3 so unit will be included
*/ */
val levDist = unitName val levDist = unitName
.substring(0, minOf(stringA.length, unitName.length)) .substring(0, minOf(stringToCompare.length, unitName.length))
.lev(stringA) .lev(stringToCompare)
// Threshold // Threshold
if (levDist < threshold) { if (levDist < threshold) {

View File

@ -84,4 +84,15 @@ class LevenshteinFilterAndSortTest {
result result
) )
} }
@Test
fun testLowerAndUpperCases() {
val searchQuery = "T"
val result = baseList.asSequence().sortByLev(searchQuery).map { it.renderedName }.toList()
println(result)
assertEquals(
listOf("Attometer", "Nanometer", "Millimeter", "Meter", "Kilometer", "Kilometer per square"),
result
)
}
} }