Is it possible to simplify this code up to 5 lines (question from interview for senior javascript developer position) ?:

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; } } }; 

  • can, see lastIndexOf() - Sergiks
  • In principle, hyphens in javascript are not significant, so any code can be written in one line - Grundy
  • @Grundy in the question the word "simplify", and you are now talking about the "cut". Can the minified code be considered simplified? I think that definitely not. - Mae
  • @NewDevelop, it all depends on the definition of simplicity - Grundy

2 answers 2

Offhand, like, like this, you can "simplify":

 function func(s, a, b) { return Math.max( s.lastIndexOf(a), s.lastIndexOf(b)); } 

But this does not correctly handle cases with empty strings in a or b . Therefore:

upd. with tests

 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); }); 

  • one
    and what happens here explain in two words please? - spectre_it
  • @Sergiks thanks for the idea, accepted. - Fox
  • @ stas0k, returns the maximum value of the indices a and b in the string s - Grundy
  • 2
    An example in which the results of the functions do not match: the function from the answer func('aba','a','b') -> 1, the function from the question func('aba','a','b') -> 2 - Grundy
  • one
    @Sergiks, in fact, and now the behavior is different :-) I added a few checks in my reply :) - Grundy

The question is not correct in principle, since indentings and line breaks are not significant in javascript, any program can be written in one line, which is what various minifiers actually use.

To simplify the code, you first need to determine what exactly this code does.

  1. when the empty line returns -1
  2. some index is searched in the loop
  3. returns the found index.

It is worth more to dwell on the cycle:

  1. exit conditions: (aIndex==-1) && (bIndex==-1) && (i>=0) they can be interpreted as - until either of the elements is found, or until the line has ended

  2. cycle body

     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--; } 

    Here you should pay attention to the definition of the index.

      if (s.substring(i, i+1) == b) 

    we write that the element is found at the current index, if the substring of one character, starting from the current one, is equal to the transferred element.

    This shows that, firstly, the parameters must be a single character, secondly, the empty string parameters will not be found, that is, you will need to return -1.

To summarize: the function returns -1 if the string is empty, or if both required parameters are empty strings, if the string is not empty and at least one of the parameters is not an empty string, then the maximum index of the parameters is returned

 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', '')); 

  • about the correctness of the question it is no longer me, this was at the interview, proposed to one of the developers))) - Fox
  • @MikhailZhuykov, added a description to the question, by the way, it is possible that some boundary values ​​still did not take into account and the results may still differ from the original function. - Grundy
  • thank you so much for your help ;-)) - Fox