index.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // TheSpanishInquisition
  2. // Cache the matrix. Note that if you not pass a limit this implementation will use a dynamically calculate one.
  3. module.exports = function(__this, that, limit) {
  4. var thisLength = __this.length,
  5. thatLength = that.length,
  6. matrix = [];
  7. // If the limit is not defined it will be calculate from this and that args.
  8. limit = (limit || ((thatLength > thisLength ? thatLength : thisLength)))+1;
  9. for (var i = 0; i < limit; i++) {
  10. matrix[i] = [i];
  11. matrix[i].length = limit;
  12. }
  13. for (i = 0; i < limit; i++) {
  14. matrix[0][i] = i;
  15. }
  16. if (Math.abs(thisLength - thatLength) > (limit || 100)){
  17. return prepare (limit || 100);
  18. }
  19. if (thisLength === 0){
  20. return prepare (thatLength);
  21. }
  22. if (thatLength === 0){
  23. return prepare (thisLength);
  24. }
  25. // Calculate matrix.
  26. var j, this_i, that_j, cost, min, t;
  27. for (i = 1; i <= thisLength; ++i) {
  28. this_i = __this[i-1];
  29. // Step 4
  30. for (j = 1; j <= thatLength; ++j) {
  31. // Check the jagged ld total so far
  32. if (i === j && matrix[i][j] > 4) return prepare (thisLength);
  33. that_j = that[j-1];
  34. cost = (this_i === that_j) ? 0 : 1; // Step 5
  35. // Calculate the minimum (much faster than Math.min(...)).
  36. min = matrix[i - 1][j ] + 1; // Deletion.
  37. if ((t = matrix[i ][j - 1] + 1 ) < min) min = t; // Insertion.
  38. if ((t = matrix[i - 1][j - 1] + cost) < min) min = t; // Substitution.
  39. // Update matrix.
  40. matrix[i][j] = (i > 1 && j > 1 && this_i === that[j-2] && __this[i-2] === that_j && (t = matrix[i-2][j-2]+cost) < min) ? t : min; // Transposition.
  41. }
  42. }
  43. return prepare (matrix[thisLength][thatLength]);
  44. /**
  45. *
  46. */
  47. function prepare(steps) {
  48. var length = Math.max(thisLength, thatLength)
  49. var relative = length === 0
  50. ? 0
  51. : (steps / length);
  52. var similarity = 1 - relative
  53. return {
  54. steps: steps,
  55. relative: relative,
  56. similarity: similarity
  57. };
  58. }
  59. };