Как узнать позицию первого вхождения разницы между двумя строками?

#javascript

#javascript

Вопрос:

Например, Hello World! и Hi World! — первое вхождение разницы находится во втором символе. Какой была бы функция JavaScript / jQuery?

Ответ №1:

Предполагая, как и другие ответы, что совпадающие строки возвращают -1 :

 // Find common prefix of strings a and b.
var prefix = function(a,b){
    return a amp;amp; a[0] === b[0] ? a[0]   prefix(a.slice(1), b.slice(1)) : '';
};

// Find index of first difference.
var diff = function(a,b){
    return a===b ? -1 : prefix(a,b).length;
};

var tests = [
    ['Hello World!', 'Hi World!'],
    ['aaabab', 'aaabzbzz'],
    ['', ''],
    ['abc', 'abc'],
    ['qrs', 'tu'],
    ['abc', ''],
    ['', 'abc']
];

console.log('diff', tests.map(test => diff(test[0], test[1])));

// Or just count up to the first difference
// Trickier nested ternary to handle the -1 however.

var diff2 = function(a,b){
    return a === b ? -1 : a[0] === b[0] ? 1   diff2(a.slice(1), b.slice(1)) : 0;
};

console.log('diff2', tests.map(test => diff2(test[0], test[1])));  

Ответ №2:

Может быть, что-то вроде этого? В таком порядке возвращается позиция первого различия, если таковое имеется, длина самой короткой строки, если они разные, или -1, если все равно.

 function findDiff(a, b) {
    a = a.toString();
    b = b.toString();
    for (var i = 0; i < Math.min(a.length, b.length); i  ) {
        if (a.charAt(i) !== b.charAt(i)) { return i; }
    }
    if (a.length !== b.length) { return Math.min(a.length, b.length); }
    return -1;
}
  

Спасибо Филу за предложения!

Комментарии:

1. Если они отличаются по первому символу, вы получите 0, но также, если строки полностью совпадают, вы получите 0. Я бы вернул -1, если они совпадают. Кроме того, если b короче, чем a, вы будете выполнять итерацию после конца b, что является ненужным и неразумным — возможно, выполнять итерацию до минимальной из двух длин.

2. @Phil очень хорошие замечания. Я написал ответ в верхней части моей головы, и у него явно есть некоторые недостатки. Я отредактирую это соответствующим образом.

Ответ №3:

 function strDiff(first, second) {
    if(first==second)
        return -1;
    first  = first.toString();
    second = second.toString();
    var minLen = min(first.length,second.length);
    for(var i = 0; i<minLen; i  ) {
        if(first.charAt(i) != second.charAt(i)) {
            return i;
        }
    }
    return minLen;
}
  

Возвращает -1, если строки не отличаются, или индекс (начинающийся с 0) символа, в котором они различаются (это длина самой короткой строки, если они отличаются только разной длиной, например, ‘abcd’ и ‘abcdef’ вернут 4.

Ответ №4:

 function firstDiff(a, b) {
    var i = 0;

    while (a.charAt(i) === b.charAt(i)) 
        if (a.charAt(i  ) === '')
            return -1;

    return i;
}
  

Возвращает позицию, в которой две строки a и b сначала отличаются, или -1, если они равны.

Более эффективная, но менее читаемая версия:

 function firstDiff(a, b) {
    for (var i = 0, c; (c = a.charAt(i)) === b.charAt(i);   i) 
        if (c === '')
            return -1;

    return i;
}
  

Если вы чувствуете, что сначала следует упорядочить аргументы, то сделайте это при вызове:

 firstDiff(toString(a), toString(b))
  

Чаще всего это будет пустой тратой времени. Знайте свои данные!