1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-12-24 16:58:51 -05:00

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
if (videos.size() > 0) {
sort(videos, new SimilarityComparator(FileUtilities.getName(getMediaFile())) {
@Override
public int compare(Object o1, Object o2) {
return super.compare(FileUtilities.getName((File) o1), FileUtilities.getName((File) o2));
}
});
sort(videos, new SimilarityComparator<File, String>(FileUtilities.getName(getMediaFile()), FileUtilities::getName));
return videos.get(0);
}
}

View File

@ -1,44 +1,46 @@
package net.filebot.similarity;
import static java.util.Collections.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.function.Function;
public class SimilarityComparator implements Comparator<Object> {
public class SimilarityComparator<T, P> implements Comparator<T> {
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.paragon = paragon;
this.mapper = mapper;
}
public SimilarityComparator(Object... paragon) {
this(new NameSimilarityMetric(), paragon);
public SimilarityComparator(P paragon, Function<T, P> mapper) {
this(new NameSimilarityMetric(), singleton(paragon), mapper.andThen(Collections::singleton));
}
@Override
public int compare(Object o1, Object o2) {
float f1 = getMaxSimilarity(o1);
float f2 = getMaxSimilarity(o2);
if (f1 == f2)
return 0;
return f1 > f2 ? -1 : 1;
public int compare(T o1, T o2) {
return Double.compare(getSimilarity(o2), getSimilarity(o1));
}
private static final double ZERO = 0;
public float getMaxSimilarity(Object obj) {
float m = 0;
for (Object it : paragon) {
m += (it != null) ? metric.getSimilarity(obj, it) : 0;
public double getSimilarity(T value) {
return paragon.stream().mapToDouble((it) -> accumulateSimilarity(it, value)).average().orElse(ZERO);
}
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;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@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 {
}