More efficient way to get LTR diffLerp editing.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Tue, 13 May 2014 19:44:01 +0000 (21:44 +0200)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Tue, 13 May 2014 19:44:01 +0000 (21:44 +0200)
string-lerp.js
tests/string-lerp.js

index 2096a07..3a30488 100644 (file)
         return s;
     }
 
-    function reverse (s) {
-        return s.split("").reverse().join("");
-    }
-
     function diffLerp(a, b, p) {
         /** Interpolate between two strings based on edit distance
 
             compute the edits. It is not recommended for strings
             longer than a few hundred characters.
          */
-        a = reverse(a);
-        b = reverse(b);
-        var edits = diff(a, b);
-        var partial = edits.slice(0, Math.round(p * edits.length));
-        return reverse(patch(partial, a));
+
+        // The edit path works from the string end, forwards, because
+        // that's how Levenshtein edits work. To match LTR reading
+        // direction (and the behavior of fastLerp), swap the strings
+        // and invert the parameter when editing.
+        var edits = diff(b, a);
+        var partial = edits.slice(0, Math.round((1 - p) * edits.length));
+        return patch(partial, b);
     }
 
     var NUMBERS = /(-?\d+(?:\.\d+)?)/g;
index 8ef0bc7..921e199 100644 (file)
@@ -73,9 +73,11 @@ JS.Test.describe('diff lerp', function () { with (this) {
     }});
 
     it("edits strings", function () { with (this) {
+        assertEqual(A, lerp(A, B, 0.01));
         assertEqual("I do not like treen eggs and ham?", lerp(A, B, 0.3));
-        assertEqual("I do not like them, Sggs and ham?", lerp(A, B, 0.5));
+        assertEqual("I do not like them, eggs and ham?", lerp(A, B, 0.5));
         assertEqual("I do not like them, Sam-Iham?", lerp(A, B, 0.9));
+        assertEqual(B, lerp(A, B, 0.99));
     }});
 }});