]>
git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blob - src/js/levenshtein.js
5 * Extend an Object with another Object's properties.
7 * The source objects are specified as additional arguments.
9 * @param dst Object the object to extend.
11 * @return Object the final object.
13 var _extend = function(dst
) {
14 var sources
= Array
.prototype.slice
.call(arguments
, 1);
15 for (var i
=0; i
<sources
.length
; ++i
) {
18 if (src
.hasOwnProperty(p
)) dst
[p
] = src
[p
];
26 * Defer execution of given function.
27 * @param {Function} func
29 var _defer = function(func
) {
30 if (typeof setImmediate
=== 'function') {
31 return setImmediate(func
);
33 return setTimeout(func
, 0);
38 * Based on the algorithm at http://en.wikipedia.org/wiki/Levenshtein_distance.
42 * Calculate levenshtein distance of the two strings.
44 * @param str1 String the first string.
45 * @param str2 String the second string.
46 * @return Integer the levenshtein distance (0 and above).
48 get: function(str1
, str2
) {
50 if (str1
=== str2
) return 0;
51 if (str1
.length
=== 0) return str2
.length
;
52 if (str2
.length
=== 0) return str1
.length
;
55 var prevRow
= new Array(str2
.length
+ 1),
56 curCol
, nextCol
, i
, j
, tmp
;
58 // initialise previous row
59 for (i
=0; i
<prevRow
.length
; ++i
) {
63 // calculate current row distance from previous row
64 for (i
=0; i
<str1
.length
; ++i
) {
67 for (j
=0; j
<str2
.length
; ++j
) {
71 nextCol
= prevRow
[j
] + ( (str1
.charAt(i
) === str2
.charAt(j
)) ? 0 : 1 );
78 tmp
= prevRow
[j
+ 1] + 1;
83 // copy current col value into previous (in preparation for next iteration)
87 // copy last col value into previous (in preparation for next iteration)
95 * Asynchronously calculate levenshtein distance of the two strings.
97 * @param str1 String the first string.
98 * @param str2 String the second string.
99 * @param cb Function callback function with signature: function(Error err, int distance)
100 * @param [options] Object additional options.
101 * @param [options.progress] Function progress callback with signature: function(percentComplete)
103 getAsync: function(str1
, str2
, cb
, options
) {
104 options
= _extend({}, {
109 if (str1
=== str2
) return cb(null, 0);
110 if (str1
.length
=== 0) return cb(null, str2
.length
);
111 if (str2
.length
=== 0) return cb(null, str1
.length
);
114 var prevRow
= new Array(str2
.length
+ 1),
117 startTime
, currentTime
;
119 // initialise previous row
120 for (i
=0; i
<prevRow
.length
; ++i
) {
128 var __calculate = function() {
130 startTime
= new Date().valueOf();
131 currentTime
= startTime
;
133 // keep going until one second has elapsed
134 while (currentTime
- startTime
< 1000) {
135 // reached end of current row?
136 if (str2
.length
<= (++j
)) {
137 // copy current into previous (in preparation for next iteration)
138 prevRow
[j
] = nextCol
;
140 // if already done all chars
141 if (str1
.length
<= (++i
)) {
142 return cb(null, nextCol
);
144 // else if we have more left to do
155 nextCol
= prevRow
[j
] + ( (str1
.charAt(i
) === str2
.charAt(j
)) ? 0 : 1 );
162 tmp
= prevRow
[j
+ 1] + 1;
167 // copy current into previous (in preparation for next iteration)
171 currentTime
= new Date().valueOf();
174 // send a progress update?
175 if (null !== options
.progress
) {
177 options
.progress
.call(null, (i
* 100.0/ str1
.length
));
179 return cb('Progress callback: ' + err
.toString());
193 if (typeof define
!== "undefined" && define
!== null && define
.amd
) {
199 else if (typeof module
!== "undefined" && module
!== null && typeof exports
!== "undefined" && module
.exports
=== exports
) {
200 module
.exports
= Levenshtein
;
203 else if (typeof self
!== "undefined" && typeof self
.postMessage
=== 'function' && typeof self
.importScripts
=== 'function') {
204 self
.Levenshtein
= Levenshtein
;
206 // browser main thread
207 else if (typeof window
!== "undefined" && window
!== null) {
208 window
.Levenshtein
= Levenshtein
;