Refactor SimilarityComparator

This commit is contained in:
Reinhard Pointner 2016-02-08 22:29:45 +00:00
parent ec0f9293c7
commit 037c3d9e68
4 changed files with 75 additions and 33 deletions

View File

@ -938,13 +938,7 @@ public class MediaBindingBean {
// still no good match found -> just take the most probable video from the same folder // still no good match found -> just take the most probable video from the same folder
if (videos.size() > 0) { if (videos.size() > 0) {
sort(videos, new SimilarityComparator(FileUtilities.getName(getMediaFile())) { sort(videos, new SimilarityComparator<File, String>(FileUtilities.getName(getMediaFile()), FileUtilities::getName));
@Override
public int compare(Object o1, Object o2) {
return super.compare(FileUtilities.getName((File) o1), FileUtilities.getName((File) o2));
}
});
return videos.get(0); return videos.get(0);
} }
} }

View File

@ -1,44 +1,46 @@
package net.filebot.similarity; package net.filebot.similarity;
import static java.util.Collections.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.function.Function;
public class SimilarityComparator<T, P> implements Comparator<T> {
public class SimilarityComparator implements Comparator<Object> {
protected SimilarityMetric metric; protected SimilarityMetric metric;
protected Object[] paragon; protected Collection<P> paragon;
protected Function<T, Collection<P>> mapper;
public SimilarityComparator(SimilarityMetric metric, Object[] paragon) { public SimilarityComparator(SimilarityMetric metric, Collection<P> paragon, Function<T, Collection<P>> mapper) {
this.metric = metric; this.metric = metric;
this.paragon = paragon; this.paragon = paragon;
this.mapper = mapper;
} }
public SimilarityComparator(P paragon, Function<T, P> mapper) {
public SimilarityComparator(Object... paragon) { this(new NameSimilarityMetric(), singleton(paragon), mapper.andThen(Collections::singleton));
this(new NameSimilarityMetric(), paragon);
} }
@Override @Override
public int compare(Object o1, Object o2) { public int compare(T o1, T o2) {
float f1 = getMaxSimilarity(o1); return Double.compare(getSimilarity(o2), getSimilarity(o1));
float f2 = getMaxSimilarity(o2);
if (f1 == f2)
return 0;
return f1 > f2 ? -1 : 1;
} }
private static final double ZERO = 0;
public float getMaxSimilarity(Object obj) { public double getSimilarity(T value) {
float m = 0; return paragon.stream().mapToDouble((it) -> accumulateSimilarity(it, value)).average().orElse(ZERO);
for (Object it : paragon) {
m += (it != null) ? metric.getSimilarity(obj, it) : 0;
} }
return m / paragon.length;
private double accumulateSimilarity(P paragon, T value) {
if (paragon == null) {
return ZERO;
} }
return mapper.apply(value).stream().mapToDouble((it) -> it == null ? ZERO : (double) metric.getSimilarity(paragon, it)).max().orElse(ZERO);
}
} }

View File

@ -0,0 +1,49 @@
package net.filebot.similarity;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
public class SimilarityComparatorTest {
private static List<String> generateWords() {
return asList("Hello", "Hallo", "12345", "Holla", "Hey", "0123456789", "Hello World", "Hello Test");
}
private static Map<String, String> generateTranslations() {
Map<String, String> m = new HashMap<>();
m.put("Hello", "Hello");
m.put("Hallo", "Hello");
m.put("Holla", "Hello");
m.put("Hey", "Hello");
return m;
}
@Test
public void defaultUsage() {
SimilarityComparator<String, String> c = new SimilarityComparator<String, String>("Hello", String::toString);
List<String> phrases = generateWords();
phrases.sort(c);
assertEquals("[Hello, Hello Test, Hello World, Hallo, 12345, Holla, Hey, 0123456789]", phrases.toString());
}
@Test
public void accumulateMapper() {
Map<String, String> dict = generateTranslations();
SimilarityComparator<String, String> c = new SimilarityComparator<String, String>(new NameSimilarityMetric(), singleton("Hello"), (it) -> asList(it, dict.get(it)));
List<String> phrases = generateWords();
phrases.sort(c);
assertEquals("[Hello, Hallo, Holla, Hey, Hello Test, Hello World, 12345, 0123456789]", phrases.toString());
}
}

View File

@ -1,14 +1,11 @@
package net.filebot.similarity; package net.filebot.similarity;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Suite; import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class) @RunWith(Suite.class)
@SuiteClasses( { SeriesNameMatcherTest.class, SeasonEpisodeMatcherTest.class, NameSimilarityMetricTest.class, NumericSimilarityMetricTest.class, SeasonEpisodeMetricTest.class }) @SuiteClasses({ SeriesNameMatcherTest.class, SeasonEpisodeMatcherTest.class, NameSimilarityMetricTest.class, NumericSimilarityMetricTest.class, SeasonEpisodeMetricTest.class, SimilarityComparatorTest.class })
public class SimilarityTestSuite { public class SimilarityTestSuite {
} }