util: Add function `get_string_diff`.

The new function specifies the single minimal diff between 2 strings.
It takes in 2 string parameters and returns an array with 3 integers
where the 1st is the index where the difference starts and the 2nd and
3rd are the indices of the end of the diff in the 2 strings.
This commit is contained in:
N-Shar-ma 2022-12-20 02:53:38 +05:30 committed by Tim Abbott
parent d1714b0671
commit 95b77c0c1a
2 changed files with 51 additions and 0 deletions

View File

@ -303,3 +303,15 @@ run_test("filter_by_word_prefix_match", () => {
]);
assert.deepEqual(util.filter_by_word_prefix_match(values, "unders", item_to_string, /\s/), []);
});
run_test("get_string_diff", () => {
assert.deepEqual(
util.get_string_diff("#ann is for updates", "#**announce** is for updates"),
[1, 4, 13],
);
assert.deepEqual(util.get_string_diff("/p", "/poll"), [2, 2, 5]);
assert.deepEqual(util.get_string_diff("Hey @Aa", "Hey @**aaron** "), [5, 7, 15]);
assert.deepEqual(util.get_string_diff("same", "same"), [0, 0, 0]);
assert.deepEqual(util.get_string_diff("same-end", "two same-end"), [0, 0, 4]);
assert.deepEqual(util.get_string_diff("space", "sp ace"), [2, 2, 3]);
});

View File

@ -402,3 +402,42 @@ export function call_function_periodically(callback: () => void, delay: number):
callback();
}
export function get_string_diff(string1: string, string2: string): [number, number, number] {
// This function specifies the single minimal diff between 2 strings. For
// example, the diff between "#ann is for updates" and "#**announce** is
// for updates" is from index 1, till 4 in the 1st string and 13 in the
// 2nd string;
let diff_start_index = -1;
for (let i = 0; i < Math.min(string1.length, string2.length); i += 1) {
if (string1.charAt(i) === string2.charAt(i)) {
diff_start_index = i;
} else {
break;
}
}
diff_start_index += 1;
if (string1.length === string2.length && string1.length === diff_start_index) {
// if the 2 strings are identical
return [0, 0, 0];
}
let diff_end_1_index = string1.length;
let diff_end_2_index = string2.length;
for (
let i = string1.length - 1, j = string2.length - 1;
i >= diff_start_index && j >= diff_start_index;
i -= 1, j -= 1
) {
if (string1.charAt(i) === string2.charAt(j)) {
diff_end_1_index = i;
diff_end_2_index = j;
} else {
break;
}
}
return [diff_start_index, diff_end_1_index, diff_end_2_index];
}