Fix result ordering
CHANGELOG.md
| 7 | 7 | Here is a list of changes that are not yet part of a release, but that will | |
| 8 | 8 | appear in next release. | |
| 9 | 9 | ||
| 10 | + | ### Bug Fix | |
| 11 | + | ||
| 12 | + | * Fix result ordering and ensure exact matches are shown first. | |
| 13 | + | ||
| 10 | 14 | ### Features | |
| 11 | 15 | ||
| 12 | 16 | * It is now possible to filter the list of dictionaries by target language. |
app/src/main/java/eu/lepiller/nani/MainActivity.java
| 9 | 9 | import androidx.annotation.NonNull; | |
| 10 | 10 | import androidx.appcompat.app.AppCompatActivity; | |
| 11 | 11 | import androidx.appcompat.widget.Toolbar; | |
| 12 | - | import androidx.fragment.app.FragmentManager; | |
| 13 | 12 | import androidx.preference.PreferenceManager; | |
| 14 | 13 | import androidx.viewpager2.widget.ViewPager2; | |
| 15 | 14 | ||
… | |||
| 28 | 27 | import com.moji4j.MojiDetector; | |
| 29 | 28 | ||
| 30 | 29 | import java.util.ArrayList; | |
| 31 | - | import java.util.Collections; | |
| 32 | 30 | import java.util.List; | |
| 33 | 31 | ||
| 34 | 32 | import eu.lepiller.nani.dictionary.DictionaryException; | |
app/src/main/java/eu/lepiller/nani/ResultPagerAdapter.java
| 130 | 130 | if(results == null) | |
| 131 | 131 | return; | |
| 132 | 132 | ||
| 133 | - | int num = 0; | |
| 134 | 133 | for(Result result: results) { | |
| 135 | - | num++; | |
| 136 | - | if (num > 10) | |
| 137 | - | break; | |
| 138 | 134 | View child_result = LayoutInflater.from(context).inflate(R.layout.layout_result, result_view, false); | |
| 139 | 135 | ||
| 140 | 136 | FuriganaTextView kanji_view = child_result.findViewById(R.id.kanji_view); |
app/src/main/java/eu/lepiller/nani/dictionary/DictionaryFactory.java
| 15 | 15 | import java.util.ArrayList; | |
| 16 | 16 | import java.util.Collections; | |
| 17 | 17 | import java.util.HashMap; | |
| 18 | + | import java.util.LinkedHashMap; | |
| 18 | 19 | import java.util.List; | |
| 19 | 20 | import java.util.Locale; | |
| 20 | 21 | import java.util.Map; | |
… | |||
| 238 | 239 | throw new NoDictionaryException(); | |
| 239 | 240 | ||
| 240 | 241 | int available = 0; | |
| 241 | - | HashMap<String, Result> results = new HashMap<>(); | |
| 242 | + | LinkedHashMap<String, Result> results = new LinkedHashMap<>(); | |
| 242 | 243 | ||
| 243 | 244 | for(Dictionary d: dictionaries) { | |
| 244 | 245 | if (d instanceof ResultDictionary && d.isDownloaded()) { | |
… | |||
| 275 | 276 | if(instance == null) | |
| 276 | 277 | throw new NoDictionaryException(); | |
| 277 | 278 | ||
| 278 | - | int available = 0; | |
| 279 | 279 | Stack<KanjiResult> results = new Stack<>(); | |
| 280 | 280 | ||
| 281 | 281 | for(Dictionary d: dictionaries) { | |
| 282 | 282 | if (d instanceof KanjiDict && d.isDownloaded()) { | |
| 283 | - | available++; | |
| 284 | 283 | KanjiResult kanjiResult = ((KanjiDict) d).search(kanji); | |
| 285 | 284 | if(kanjiResult != null) { | |
| 286 | 285 | results.add(kanjiResult); | |
app/src/main/java/eu/lepiller/nani/dictionary/ResultDictionary.java
| 8 | 8 | import java.io.RandomAccessFile; | |
| 9 | 9 | import java.util.ArrayList; | |
| 10 | 10 | import java.util.Arrays; | |
| 11 | + | import java.util.Collections; | |
| 11 | 12 | ||
| 12 | 13 | import eu.lepiller.nani.result.Result; | |
| 13 | 14 | ||
… | |||
| 77 | 78 | Log.v(TAG, "Getting values"); | |
| 78 | 79 | int valuesLength = file.readShort(); | |
| 79 | 80 | ArrayList<Integer> results = new ArrayList<>(); | |
| 81 | + | ArrayList<Integer> exactResults = new ArrayList<>(); | |
| 80 | 82 | ||
| 81 | 83 | Log.v(TAG, "Number of values: " + valuesLength); | |
| 82 | 84 | for(int i=0; i<valuesLength; i++) { | |
| 83 | - | results.add(file.readInt()); | |
| 85 | + | exactResults.add(file.readInt()); | |
| 84 | 86 | } | |
| 85 | 87 | ||
| 86 | 88 | int transitionLength = file.readByte(); | |
… | |||
| 95 | 97 | results.addAll(getValues(file, others[i])); | |
| 96 | 98 | } | |
| 97 | 99 | ||
| 98 | - | Log.v(TAG, "result size: " + results.size()); | |
| 99 | - | return results; | |
| 100 | + | Collections.sort(results); | |
| 101 | + | Collections.sort(exactResults); | |
| 102 | + | ||
| 103 | + | Log.v(TAG, "exact result size: " + exactResults.size() + ", result size: " + results.size()); | |
| 104 | + | Log.v(TAG, "exact: " + Arrays.toString(exactResults.toArray()) + ", others: " + Arrays.toString(results.toArray())); | |
| 105 | + | exactResults.addAll(results); | |
| 106 | + | return exactResults; | |
| 100 | 107 | } | |
| 101 | 108 | ||
| 102 | 109 | private ArrayList<Integer> searchTrie(RandomAccessFile file, long triePos, byte[] txt) throws IOException { | |
… | |||
| 185 | 192 | uniqResults.add(i); | |
| 186 | 193 | } | |
| 187 | 194 | ||
| 188 | - | int[] uniqResultsArray = new int[uniqResults.size()]; | |
| 189 | - | for(int i=0; i<uniqResults.size(); i++) { | |
| 190 | - | uniqResultsArray[i] = uniqResults.get(i); | |
| 191 | - | } | |
| 192 | - | Arrays.sort(uniqResultsArray); | |
| 193 | - | ||
| 194 | - | Log.v(TAG, uniqResults.toString()); | |
| 195 | + | Log.v(TAG, Arrays.toString(uniqResults.toArray())); | |
| 195 | 196 | ||
| 196 | 197 | int num = 0; | |
| 197 | - | for(int i: uniqResultsArray) { | |
| 198 | + | for(int i: uniqResults) { | |
| 198 | 199 | if(num > 10) | |
| 199 | 200 | break; | |
| 200 | 201 | num++; | |
| 201 | - | r.add(0, getValue(file, i)); | |
| 202 | + | r.add(getValue(file, i)); | |
| 202 | 203 | } | |
| 203 | 204 | return r; | |
| 204 | 205 | } catch (FileNotFoundException e) { | |
app/src/main/res/layout/layout_result.xml
| 4 | 4 | android:layout_height="wrap_content" | |
| 5 | 5 | xmlns:app="http://schemas.android.com/apk/res-auto" | |
| 6 | 6 | android:orientation="vertical" | |
| 7 | - | android:layout_marginBottom="8dp"> | |
| 7 | + | android:layout_marginBottom="8dp" | |
| 8 | + | android:layout_marginTop="8dp"> | |
| 8 | 9 | ||
| 9 | 10 | <LinearLayout | |
| 10 | 11 | android:layout_width="wrap_content" |