From 67d1040113d0d68677308d25d43930f1cae9840e Mon Sep 17 00:00:00 2001 From: imkiva Date: Sun, 25 Mar 2018 01:50:04 +0800 Subject: [PATCH] Improve: package sort algorithms --- .../neoterm/ui/pm/PackageManagerActivity.kt | 45 +++++++++++-------- .../neoterm/ui/pm/utils/StringDistance.java | 38 ++++++++++++++++ 2 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java diff --git a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt index 4e4ddde..052e907 100644 --- a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt +++ b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt @@ -18,16 +18,14 @@ import android.widget.Toast import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter import io.neoterm.R import io.neoterm.backend.TerminalSession -import io.neoterm.component.pm.PackageComponent -import io.neoterm.component.pm.Source -import io.neoterm.component.pm.SourceManager -import io.neoterm.component.pm.SourceHelper +import io.neoterm.component.pm.* import io.neoterm.frontend.component.ComponentManager import io.neoterm.frontend.config.NeoPreference import io.neoterm.frontend.config.NeoTermPath import io.neoterm.frontend.floating.TerminalDialog import io.neoterm.ui.pm.adapter.PackageAdapter import io.neoterm.ui.pm.model.PackageModel +import io.neoterm.ui.pm.utils.StringDistance import io.neoterm.utils.PackageUtils /** @@ -232,18 +230,25 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen }.start() } - private fun filter(models: List, query: String?): List { - val filteredModelList = ArrayList() - if (query != null) { - val lowerCaseQuery = query.toLowerCase() - for (model in models) { - val name = model.packageInfo.packageName!!.toLowerCase() - val desc = model.packageInfo.description!!.toLowerCase() - if (name.contains(lowerCaseQuery) || desc.contains(lowerCaseQuery)) { - filteredModelList.add(model) - } - } + private fun sortDistance(models: List, query: String, + mapper: (NeoPackageInfo) -> String): List> { + return models + .map({ + Pair(it, StringDistance.distance(mapper(it.packageInfo).toLowerCase(), query.toLowerCase())) + }) + .sortedWith(Comparator { l, r -> r.second.compareTo(l.second) }) + .toList() + } + + private fun filter(models: List, query: String): List { + val filteredModelList = mutableListOf() + val prepared = models.filter { + it.packageInfo.packageName!!.contains(query, true) + || it.packageInfo.description!!.contains(query, true) } + + sortDistance(prepared, query, { it.packageName!! }).mapTo(filteredModelList, { it.first }) + sortDistance(prepared, query, { it.description!! }).mapTo(filteredModelList, { it.first }) return filteredModelList } @@ -252,10 +257,12 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen } override fun onQueryTextChange(text: String?): Boolean { - val filteredModelList = filter(models, text) - adapter.edit() - .replaceAll(filteredModelList) - .commit() + if (text != null) { + val filteredModelList = filter(models, text) + adapter.edit() + .replaceAll(filteredModelList) + .commit() + } return true } diff --git a/app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java b/app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java new file mode 100644 index 0000000..14f9b20 --- /dev/null +++ b/app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java @@ -0,0 +1,38 @@ +package io.neoterm.ui.pm.utils; + +/** + * @author kiva + */ + +public class StringDistance { + public static int distance(String source, String target) { + char[] sources = source.toCharArray(); + char[] targets = target.toCharArray(); + int sourceLen = sources.length; + int targetLen = targets.length; + + int[][] d = new int[sourceLen + 1][targetLen + 1]; + for (int i = 0; i <= sourceLen; i++) { + d[i][0] = i; + } + for (int i = 0; i <= targetLen; i++) { + d[0][i] = i; + } + + for (int i = 1; i <= sourceLen; i++) { + for (int j = 1; j <= targetLen; j++) { + if (sources[i - 1] == targets[j - 1]) { + d[i][j] = d[i - 1][j - 1]; + } else { + int insert = d[i][j - 1] + 1; + int delete = d[i - 1][j] + 1; + int replace = d[i - 1][j - 1] + 1; + d[i][j] = Math.min(insert, delete) > Math.min(delete, replace) + ? Math.min(delete, replace) + : Math.min(insert, delete); + } + } + } + return d[sourceLen][targetLen]; + } +}