-
Notifications
You must be signed in to change notification settings - Fork 12
Introduced fastDiff() #238
Conversation
src/fastdiff.js
Outdated
* Finds position of the first and last change in the given strings and generates set of changes. Set of changes | ||
* can be applied to the input text in order to transform it into the output text, for example: | ||
* | ||
* let input = '12abc3'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add at least two more, basic examples. One example: adding a few consecutive characters somewhere in the string. Second example: removing a few consecutive characters from the string. The example you provided is actually kind of an edge case, where characters were removed from the beginning and from the end. So, the output might actually be surprising for someone.
Other than that, I am not sure about the "usage" snippet. I have a feeling that the example is a bit uninspiring. Even though it shows how to use the output, somebody would think "why would I want to do it?". I have a feeling that we might want to drop this snippet.
I'd also shorten the examples:
* (...) for example:
*
* fastDiff( '12a', '12xyza' ); // [ { ... } ]
* fastDiff( '12a', '12aa' ); // [ { ... } ]
* fastDiff( '12xyza', '12a' ); // [ { ... } ]
* fastDiff( '12aa', '12a' ); // [ { ... } ]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the output is too long for the comment in the same line, it can be above or below starting with "Following produces:" and with extra line between each example.
src/fastdiff.js
Outdated
// The above indexes means that in `oldText` modified part is `1[23]4` and in the `newText` it is `1[342]4`. | ||
// Based on such indexes, array with `insert`/`delete` operations which allows transforming | ||
// old text to the new one could be generated. | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it return correct values if strings are the same? If not, then I'd add a note that it is assumed that the strings are different.
src/fastdiff.js
Outdated
// If not found, it means first change is at the end of the string. | ||
let firstIndex = oldTextLength; | ||
for ( let i = 0; i < oldTextLength; i++ ) { | ||
if ( i >= newTextLength || oldText[ i ] !== newText[ i ] ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i >= newTextLength
should not be needed. If it is true, then newText[ i ] == undefined
so surely the second condition will be met.
src/fastdiff.js
Outdated
// oldText: '321ba' -> '21ba' -> 'ab12' | ||
// newText: '31ba' -> '1ba' -> 'ab1' | ||
// { firstIndex: 1, lastIndexOld: 2, lastIndexNew: 1 } | ||
if ( i >= newTextReversedLength ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those additional conditions are probably not needed either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, unfortunately, it is needed, because otherwise, calculations mess up in the last if
. There's a difference if the texts differ because of an actual different letter or because of one of them is shorter.
I've spent some time analyzing this code, cause it looked to me that the So, the algorithm itself cannot be simpler. Of course, finding the first change is easy. Finding the last change is more difficult. Cutting and reversing the string leads in fact to the simpler implementation (you could do the same using proper offsets but it would be even worse). However, I think that it may be written in a simpler way. I'll propose something. |
I've pushed two commits. In the first one, I only changed @f1ames solution a bit. In the second one, I proposed a different solution. Since I am subjective on this matter, maybe @Reinmar could take a look and say which solution looks cleaner. BTW. Because of a non-precise description in
Because both of them differ on the third index, both of them should have |
BTW. I've also added two tests - one that I thought should fail for my algorithm, and the one that is used in the docs. |
I'm sure you'll be able to figure out which one you like more, guys ;) You know far more about this code than I'll be able to learn now. |
src/fastdiff.js
Outdated
// @param {String} newText | ||
// @returns {Object} | ||
// @returns {Number} return.firstIndex Index of the first change in both strings (always the same for both). | ||
// @returns {Number} result.lastIndexOld Index of the last common character in `oldText` string looking from back. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be:
result.lastIndexOld Index of the last common character in
oldText
string.
or
result.lastIndexOld Index of the first common character in
oldText
string looking from back.
Because looking for the last common character starting from the back, means you are looking for the first common character basically.
I just added some docs improvements. TBH @scofalik, your refactor made it more readable and simplified it a little so I'm fine with it. Looks good IMHO.
I see you left the snippet, was it on purpose? I wasn't sure either, but it gives some general picture how Merged latest changes from I think it is ready for review, from my perspective it looks good, nothing to add here. |
As agreed with @scofalik F2F, I have merged the PR as it was ready 🎉 |
Suggested merge commit message (convention)
Other: Introduced
fastDiff
diffing function. Closes ckeditor/ckeditor5#5000.Additional information
See ckeditor/ckeditor5#5000 for more details.