@@ -37,6 +37,11 @@ class Similarity extends SequenceMatcher
37
37
* @var array Count of each unique sequence at version 2.
38
38
*/
39
39
private $ uniqueCount2 ;
40
+ /**
41
+ * @var array Contains the indexes of lines which are stripped from the sequences by Similarity::stripLines().
42
+ * @see Similarity::stripLines()
43
+ */
44
+ private $ stripped = ['old ' => [], 'new ' => []];
40
45
41
46
42
47
/**
@@ -65,15 +70,22 @@ public function setSeq2($version2)
65
70
*/
66
71
public function getSimilarity (int $ type = self ::CALC_DEFAULT ): float
67
72
{
73
+ if ($ this ->options ['ignoreLines ' ]) {
74
+ // Backup original sequences and filter non blank lines.
75
+ $ this ->stripLines ();
76
+ }
77
+
68
78
switch ($ type ) {
69
79
case self ::CALC_FAST :
70
- return $ this ->getRatioFast ();
80
+ $ ratio = $ this ->getRatioFast ();
81
+ $ this ->restoreLines ();
82
+ break ;
71
83
case self ::CALC_FASTEST :
72
- return $ this ->getRatioFastest ();
84
+ $ ratio = $ this ->getRatioFastest ();
85
+ $ this ->restoreLines ();
86
+ break ;
73
87
default :
74
- if ($ this ->options ['ignoreLines ' ]) {
75
- $ this ->stripLines ();
76
- }
88
+ $ this ->setSequences ($ this ->old , $ this ->new );
77
89
$ matches = array_reduce (
78
90
$ this ->getMatchingBlocks (),
79
91
function ($ carry , $ item ) {
@@ -82,8 +94,44 @@ function ($carry, $item) {
82
94
0
83
95
);
84
96
85
- return $ this ->calculateRatio ($ matches , count ($ this ->old ) + count ($ this ->new ));
86
- // TODO: Restore original (un-stripped) versions?
97
+ $ ratio = $ this ->calculateRatio ($ matches , count ($ this ->old ) + count ($ this ->new ));
98
+ $ this ->restoreLines ();
99
+ $ this ->setSequences ($ this ->old , $ this ->new );
100
+ }
101
+
102
+ return $ ratio ;
103
+ }
104
+
105
+ /**
106
+ * Strip empty or blank lines from the sequences to compare.
107
+ *
108
+ */
109
+ private function stripLines (): void
110
+ {
111
+ foreach (['old ' , 'new ' ] as $ version ) {
112
+ // Remove empty lines.
113
+ $ this ->$ version = array_filter (
114
+ $ this ->$ version ,
115
+ function ($ line , $ index ) use ($ version ) {
116
+ $ sanitizedLine = $ line ;
117
+ if ($ this ->options ['ignoreLines ' ] == self ::DIFF_IGNORE_LINE_BLANK ) {
118
+ $ sanitizedLine = trim ($ line );
119
+ }
120
+
121
+ if ($ sanitizedLine == '' ) {
122
+ // Store line to be able to restore later.
123
+ $ this ->stripped [$ version ][$ index ] = $ line ;
124
+
125
+ return false ;
126
+ }
127
+
128
+ return true ;
129
+ },
130
+ ARRAY_FILTER_USE_BOTH
131
+ );
132
+
133
+ // Re-index sequence.
134
+ $ this ->$ version = array_values ($ this ->$ version );
87
135
}
88
136
}
89
137
@@ -97,6 +145,7 @@ function ($carry, $item) {
97
145
private function getRatioFast (): float
98
146
{
99
147
if ($ this ->uniqueCount2 === null ) {
148
+ // Build unless cached.
100
149
$ this ->uniqueCount2 = [];
101
150
$ bLength = count ($ this ->new );
102
151
for ($ iterator = 0 ; $ iterator < $ bLength ; ++$ iterator ) {
@@ -140,6 +189,15 @@ private function calculateRatio(int $matches, int $length = 0): float
140
189
return $ returnValue ;
141
190
}
142
191
192
+ private function restoreLines ()
193
+ {
194
+ foreach (['old ' , 'new ' ] as $ version ) {
195
+ foreach ($ this ->stripped [$ version ] as $ index => $ line ) {
196
+ array_splice ($ this ->$ version , $ index , 0 , $ line );
197
+ }
198
+ }
199
+ }
200
+
143
201
/**
144
202
* Return an upper bound ratio really quickly for the similarity of the strings.
145
203
*
@@ -155,34 +213,6 @@ private function getRatioFastest(): float
155
213
return $ this ->calculateRatio (min ($ aLength , $ bLength ), $ aLength + $ bLength );
156
214
}
157
215
158
- /**
159
- * Strip empty or blank lines from the sequences to compare.
160
- *
161
- */
162
- private function stripLines (): void
163
- {
164
- foreach (['old ' , 'new ' ] as $ version ) {
165
- if ($ this ->options ['ignoreLines ' ] == self ::DIFF_IGNORE_LINE_BLANK ) {
166
- array_walk (
167
- $ this ->$ version ,
168
- function (&$ line ) {
169
- $ line = trim ($ line );
170
- }
171
- );
172
- unset($ line );
173
- }
174
-
175
- $ this ->$ version = array_filter (
176
- $ this ->$ version ,
177
- function ($ line ) {
178
- return $ line != '' ;
179
- }
180
- );
181
- }
182
-
183
- $ this ->setSequences (array_values ($ this ->old ), array_values ($ this ->new ));
184
- }
185
-
186
216
/**
187
217
* Helper function to calculate the number of matches for Ratio().
188
218
*
0 commit comments