Merge pull request #867 from pszklarska/fix_844

Fixing #844 - If a category has exact name entered, show it first
This commit is contained in:
Nicolas Raoul 2017-10-02 16:32:46 +09:00 committed by GitHub
commit 9b8d8e9b7c
4 changed files with 108 additions and 9 deletions

View file

@ -12,20 +12,24 @@ dependencies {
compile 'ch.acra:acra:4.7.0'
compile 'org.mediawiki:api:1.3'
compile 'commons-codec:commons-codec:1.10'
compile "com.android.support:support-v4:${project.supportLibVersion}"
compile "com.android.support:appcompat-v7:${project.supportLibVersion}"
compile "com.android.support:design:${project.supportLibVersion}"
compile 'com.google.code.gson:gson:2.8.0'
compile "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
compile 'com.github.pedrovgs:renderers:3.3.3'
annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.jakewharton.timber:timber:4.5.1'
compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.squareup.okio:okio:1.13.0'
compile 'info.debatty:java-string-similarity:0.24'
compile ('com.mapbox.mapboxsdk:mapbox-android-sdk:5.1.0@aar'){
transitive=true
}
compile "com.android.support:support-v4:${project.supportLibVersion}"
compile "com.android.support:appcompat-v7:${project.supportLibVersion}"
compile "com.android.support:design:${project.supportLibVersion}"
compile "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.squareup.okio:okio:1.13.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.

View file

@ -25,6 +25,7 @@ import com.pedrogomez.renderers.RVRendererAdapter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -36,6 +37,7 @@ import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.data.Category;
import fr.free.nrw.commons.upload.MwVolleyApi;
import fr.free.nrw.commons.utils.StringSortingUtils;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -107,7 +109,7 @@ public class CategorizationFragment extends Fragment {
RxTextView.textChanges(categoriesFilter)
.takeUntil(RxView.detaches(categoriesFilter))
.debounce(300, TimeUnit.MILLISECONDS)
.debounce(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(filter -> updateCategoryList(filter.toString()));
return rootView;
@ -200,6 +202,7 @@ public class CategorizationFragment extends Fragment {
)
.filter(categoryItem -> !containsYear(categoryItem.getName()))
.distinct()
.sorted(sortBySimilarity(filter))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
s -> categoriesAdapter.add(s), Timber::e, () -> {
@ -221,6 +224,12 @@ public class CategorizationFragment extends Fragment {
);
}
private Comparator<CategoryItem> sortBySimilarity(final String filter) {
Comparator<String> stringSimilarityComparator = StringSortingUtils.sortBySimilarity(filter);
return (firstItem, secondItem) -> stringSimilarityComparator
.compare(firstItem.getName(), secondItem.getName());
}
private List<String> getStringList(List<CategoryItem> input) {
List<String> output = new ArrayList<>();
for (CategoryItem item : input) {

View file

@ -0,0 +1,46 @@
package fr.free.nrw.commons.utils;
import java.util.Comparator;
import info.debatty.java.stringsimilarity.Levenshtein;
public class StringSortingUtils {
private StringSortingUtils() {
//no-op
}
/**
* Returns Comparator for sorting strings by its similarity with Levenshtein
* algorithm. By using this Comparator we get results from the highest to
* the lowest match.
*
* @param filter pattern to compare similarity
* @return Comparator with string similarity
*/
public static Comparator<String> sortBySimilarity(final String filter) {
return (firstItem, secondItem) -> {
double firstItemSimilarity = calculateSimilarity(firstItem, filter);
double secondItemSimilarity = calculateSimilarity(secondItem, filter);
return (int) Math.signum(secondItemSimilarity - firstItemSimilarity);
};
}
private static double calculateSimilarity(String firstString, String secondString) {
String longer = firstString.toLowerCase();
String shorter = secondString.toLowerCase();
if (firstString.length() < secondString.length()) {
longer = secondString;
shorter = firstString;
}
int longerLength = longer.length();
if (longerLength == 0) {
return 1.0;
}
double distanceBetweenStrings = new Levenshtein().distance(longer, shorter);
return (longerLength - distanceBetweenStrings) / (double) longerLength;
}
}

View file

@ -0,0 +1,40 @@
package fr.free.nrw.commons.utils;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
public class StringSortingUtilsTest {
@Test
public void testSortingNumbersBySimilarity() throws Exception {
List<String> actualList = Arrays.asList("1234567", "4567", "12345", "123", "1234");
List<String> expectedList = Arrays.asList("1234", "12345", "123", "1234567", "4567");
Collections.sort(actualList, StringSortingUtils.sortBySimilarity("1234"));
Assert.assertEquals(expectedList, actualList);
}
@Test
public void testSortingTextBySimilarity() throws Exception {
List<String> actualList = Arrays.asList("The quick brown fox",
"quick brown fox",
"The",
"The quick ",
"The fox",
"brown fox",
"fox");
List<String> expectedList = Arrays.asList("The",
"The fox",
"The quick ",
"The quick brown fox",
"quick brown fox",
"brown fox",
"fox");
Collections.sort(actualList, StringSortingUtils.sortBySimilarity("The"));
Assert.assertEquals(expectedList, actualList);
}
}