Passed
Push — master ( 2433d5...5c4556 )
by Akpé Aurelle Emmanuel Moïse
47s queued 10s
created

jaroWinklerDistance   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 41
dl 0
loc 71
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A prepareJaroWinkler() 0 12 1
A jaroWinkler() 0 12 4
A getJWDistance() 0 16 3
A _jwMatches() 0 12 5
A jwMatches() 0 5 3
1
<?php
2
3
/**
4
*
5
* @Name : similar-text
6
* @Programmer : Akpé Aurelle Emmanuel Moïse Zinsou
7
* @Date : 2019-04-01
8
* @Released under : https://github.com/manuwhat/similar-text/blob/master/LICENSE
9
* @Repository : https://github.com/manuwhat/similar
10
*
11
**/
12
13
14
namespace EZAMA{
15
    class jaroWinklerDistance extends distance
16
    {
17
        public static function jaroWinkler($a, $b, $round = 2)
18
        {
19
            if (!is_string($a) || !is_string($b)) {
20
                return false;
21
            }
22
            static $distance = array();
23
            static $previous = array();
24
            if (array($a, $b) === $previous) {
25
                return $distance;
26
            }
27
            $previous = array($a, $b);
28
            return self::getJWDistance($a, $b, $distance, $round);
29
        }
30
        
31
        
32
        
33
        private static function getJWDistance(&$a, &$b, &$distance, $round)
34
        {
35
            extract(self::prepareJaroWinkler($a, $b));
36
            for ($i = 0, $min = min(count((array) $a), count((array) $b)), $t = 0; $i < $min; $i++) {
37
                if ($a[$i] !== $b[$i]) {
38
                    $t++;
39
                }
40
            }
41
            $t /= 2;
42
            $distance['jaro'] = 1 / 3 * ($corresponding / $ca + $corresponding / $cb + ($corresponding - $t) / $corresponding);
43
            $distance['jaro-winkler'] = $distance['jaro'] + (min($longCommonSubstr, 4) * 0.1 * (1 - $distance['jaro']));
44
            $distance = array_map(function($v) use ($round) {
45
                return round($v, $round);
46
            }, $distance);
47
            
48
            return $distance;
49
        }
50
        
51
        private static function prepareJaroWinkler(&$a, &$b)
52
        {
53
            $a = self::split($a);
54
            $b = self::split($b);
55
            $transpositions = array('a'=>array(), 'b'=>array(), 'corresponding'=>0, 'longCommonSubstr'=>0, 'ca'=>count((array) $a), 'cb'=>count((array) $b));
56
            $Δ = max($transpositions['ca'], $transpositions['cb']) / 2 - 1;
57
            self::jwMatches($a, $b, $transpositions, $Δ);
58
            ksort($transpositions['a']);
59
            ksort($transpositions['b']);
60
            $transpositions['a'] = array_values($transpositions['a']);
61
            $transpositions['b'] = array_values($transpositions['b']);
62
            return $transpositions;
63
        }
64
        
65
        private static function jwMatches(&$a, &$b, &$transpositions, $Δ)
66
        {
67
            foreach ($a as $ind=>$chr) {
68
                foreach ($b as $index=>$char) {
69
                    self::_jwMatches($chr, $char, $index, $ind, $transpositions, $Δ);
70
                }
71
            }
72
        }
73
        
74
        private static function _jwMatches($chr, $char, $index, $ind, &$transpositions, $Δ)
75
        {
76
            if ($chr === $char && (abs($index - $ind) <= $Δ)) {
77
                if ($ind !== $index) {
78
                    $transpositions['a'][$ind] = $chr;
79
                    $transpositions['b'][$index] = $char;
80
                } else {
81
                    if ($ind - 1 <= $transpositions['longCommonSubstr']) {
82
                        $transpositions['longCommonSubstr']++;
83
                    }
84
                }
85
                $transpositions['corresponding']++;
86
            }
87
        }
88
    }
89
    
90
}
91