#javascript #инспекция_кода
Можно ли упростить этот код до 5 строк (вопрос из собеседования на позицию senior javascript developer)?: function func(s, a, b) { var match_empty=/^$/ ; if (s.match(match_empty)) { return -1; } else { var i=s.length-1; var aIndex=-1; var bIndex=-1; while ((aIndex==-1) && (bIndex==-1) && (i>=0)) { if (s.substring(i, i+1) == a) aIndex=i; if (s.substring(i, i+1) == b) bIndex=i; i--; } if (aIndex != -1) { if (bIndex == -1) return aIndex; else return Math.max(aIndex, bIndex); } else { if (bIndex != -1) return bIndex; else return -1; } } };
Ответы
Ответ 1
Навскидку, вроде бы, вот так можно «упростить»: function func(s, a, b) { return Math.max( s.lastIndexOf(a), s.lastIndexOf(b)); } Но это не правильно обработает случаи с пустыми строками в a или b. Поэтому: upd. с тестами function funcSergiks(s, a, b) { return Math.max( (a.length ? s.lastIndexOf(a) : -1), (b.length ? s.lastIndexOf(b) : -1) ) } // --------------------------------------- function func(s, a, b) { var match_empty = /^$/; if (s.match(match_empty)) { return -1; } else { var i = s.length - 1; var aIndex = -1; var bIndex = -1; while ((aIndex == -1) && (bIndex == -1) && (i >= 0)) { if (s.substring(i, i + 1) == a) aIndex = i; if (s.substring(i, i + 1) == b) bIndex = i; i--; } if (aIndex != -1) { if (bIndex == -1) return aIndex; else return Math.max(aIndex, bIndex); } else { if (bIndex != -1) return bIndex; else return -1; } } }; var tests = [ [ ['google', 'g', 'o'], 3 ], [ ['aba', 'a', 'b'], 2 ], [ ['', 'g', 'o'], -1 ], [ ['google', 'x', 'o'], 2 ], [ ['aba', '', ''], -1 ], [ ['aba', 'a', ''], 2 ], [ ['aba', '', 'b'], 1 ], [ ['aba', 'a', 'b'], 2 ], ]; tests.forEach(test => { var a = func.apply(this, test[0]); var b = funcSergiks.apply(this, test[0]); console.log(a == b && b == test[1] ? "PASSED" : "FAILED", JSON.stringify(test), a, b); });Ответ 2
Вопрос в принципе не корректен, так как в яваскрипте не значимы отступы и переносы строк, любую программу можно записать в одну строку, чем собственно и пользуются различные минификаторы. Для упрощения кода, сначала нужно определить, что именно делает данный код. при пустой строке возвращается -1 в цикле ищется какой-то индекс возвращается найденный индекс. Стоит подробнее остановиться на цикле: условия выхода: (aIndex==-1) && (bIndex==-1) && (i>=0) их можно интерпретировать как - пока не найден любой из элементов, либо пока не кончилась строка тело цикла while ((aIndex==-1) && (bIndex==-1) && (i>=0)) { if (s.substring(i, i+1) == a) aIndex=i; if (s.substring(i, i+1) == b) bIndex=i; i--; } Тут стоит обратить внимание на определение индекса. if (s.substring(i, i+1) == b) записываем, что элемент найден по текущему индексу, если подстрока из одного символа, начиная с текущего равна переданному элементу. Это показывает, что, во-первых, параметры должны быть одним символом, во-вторых, параметры пустые строки не будут найдены, то есть нужно будет возвращать -1. Если подвести итог: функция возвращает -1, если строка пустая, либо если оба искомых параметра пустые строки, если строка не пустая и хотя бы один из параметров не пустая строка, то возвращается максимальный индекс из параметров function func(s, a, b) { if (s == '' || (a == '' && b == '')) return -1; for (var i = s.length; --i >= 0;) if (s[i] == a || s[i] == b) return i; }; console.log('func', func('aba', 'a', 'b')); console.log('func', func('aba', '', '')); console.log('func', func('aba', '', 'b')); console.log('func', func('aba', 'a', '')); function funcSrc(s, a, b) { var match_empty = /^$/; if (s.match(match_empty)) { return -1; } else { var i = s.length - 1; var aIndex = -1; var bIndex = -1; while ((aIndex == -1) && (bIndex == -1) && (i >= 0)) { if (s.substring(i, i + 1) == a) aIndex = i; if (s.substring(i, i + 1) == b) bIndex = i; i--; } if (aIndex != -1) { if (bIndex == -1) return aIndex; else return Math.max(aIndex, bIndex); } else { if (bIndex != -1) return bIndex; else return -1; } } }; console.log('funcSrc', funcSrc('aba', 'a', 'b')); console.log('funcSrc', funcSrc('aba', '', '')); console.log('funcSrc', funcSrc('aba', '', 'b')); console.log('funcSrc', funcSrc('aba', 'a', '')); function funcIndexOf(s, a, b) { return Math.max(s.indexOf(a), s.indexOf(b)); } console.log('funcIndexOf', funcIndexOf('aba', 'a', 'b')); console.log('funcIndexOf', funcIndexOf('aba', '', '')); console.log('funcIndexOf', funcIndexOf('aba', '', 'b')); console.log('funcIndexOf', funcIndexOf('aba', 'a', '')); function funcLastIndexOf(s, a, b) { return Math.max(s.lastIndexOf(a), s.lastIndexOf(b)); } console.log('funcLastIndexOf', funcLastIndexOf('aba', 'a', 'b')); console.log('funcLastIndexOf', funcLastIndexOf('aba', '', '')); console.log('funcLastIndexOf', funcLastIndexOf('aba', '', 'b')); console.log('funcLastIndexOf', funcLastIndexOf('aba', 'a', ''));
Комментариев нет:
Отправить комментарий