I solve problems that are set at the interview.

Required : write a recursive function that flips a string.

I independently decided in two ways that were different from each other, but which one is preferable and why I cannot determine without your help.

And I would be glad to see more optimal options.

I method:

function repl_str(str) { if (typeof str == "string") str = { str: str, index: 0, buff: "" }; else if (str.index >= str.str.length) return str.buff; str.buff += str.str.substring(str.str.length - (str.index + 1), str.str.length - str.index); str.index++; return repl_str(str); } repl_str("test"); //tset 

II method:

 function repl_str(str, stack) { if (typeof stack == "undefined") { stack = {}; stack.index = 0; stack.buff = ""; } else if (stack.index >= str.length) return stack.buff; stack.buff += str.substring(str.length - (stack.index + 1), str.length - stack.index); stack.index++; return repl_str(str, stack); } repl_str("test"); //tset 
  • Write tests, check both functions for correct behavior. Write more tests and test both functions for speed. Your result. - Kromster
  • But can you ask where this task is from? You were simply asked to tie a tie around your neck through .... Yes, with the help of recursion you can do anything, but this does not mean that an experienced programmer who constantly deals with recursion will be able to reverse the string with a half-kick. In life, recursion is not so used and therefore the brain cannot understand what it is asked for. And the bad thing about the code is that at some point the arguments change their type from a string to a target, and it is also doubtful to use a substring. And it was also necessary to clarify which parameters are valid, but ideally there should always be a string. - vas
  • And it was necessary to ask about the internals of the recursive function, what exactly can be used there. Recursion is not even in the best frameworks, because it is not gentle, it is slow. It is used only when walking around trees .. - vas
  • one
    IMHO, this task is simply done through Array.prototype.reverse (); jsfiddle.net/IonDen/a4p8yceh var test = "Very long text"; function reverse (str) {var temp = str.split (''); temp.reverse (); return temp.join (''); } reverse (test) - IonDen

6 answers 6

somehow I probably wanted to

 function r(a) { return a === '' ? '' : r(a.slice(1)) + a[0]; } 

without slice:

 function r(a,n) { n = typeof n === 'undefined' ? a.length - 1 : n - 1; return n >= 0 ? a[n] + r(a, n) : ''; } 

but the last one is some kind of silly recursion.

for the slice option came up with "optimization" (-1 call)

 function r(a) { return a.length - 1 ? r(a.slice(1)) + a[0] : a; }; 

ES6:

 const r = (a) => a.length - 1 ? r(a.slice(1)) + a[0] : a; 

spied such a hack for recursion on switch functions

 ( ( a, r = (a) => a.length-1 ? r(a.slice(1)) + a[0] : a // дефолтный параметр r ) => r(a) )("abcdef"); 

even then I forgot about reverse: :)

 "12345".split('').reverse().join(''); 
  • The first is just cool! - vas

It is possible so for example.

 function r(s){return s.length == 0 ? s : r(s.substring(1)).concat(s.charAt(0));} 

UPD : refactored to one line.

Recursion expansion:

 r("Лезу в узеЛ") (r("Лезу в узе")) + "Л" ((r("Лезу в уз")) + "е") + "Л" (((r("Лезу в у")) + "з") + "e") + "Л" ((((r("Лезу в ")) + "у") + "з") + "e") + "Л" (((((r("Лезу в")) + " ") + "у") + "з") + "e") + "Л" ((((((r("Лезу ")) + "в") + " ") + "у") + "з") + "e") + "Л" (((((((r("Лезу")) + " ") + "в") + " ") + "у") + "з") + "e") + "Л" ((((((((r("Лез")) + "у") + " ") + "в") + " ") + "у") + "з") + "e") + "Л" (((((((((r("Ле")) + "з") + "у") + " ") + "в") + " ") + "у") + "з") + "e") + "Л" ((((((((((r("Л")) + "e") + "з") + "у") + " ") + "в") + " ") + "у") + "з") + "e") + "Л" 

But actually a symmetrical version, they say that it is twice as slow as asymmetric:

 function r(s) { if (s.length < 2) return s; var halfIndex = Math.ceil(s.length / 2); return r(s.substr(halfIndex)) + r(s.substr(0, halfIndex)); } 

    And why has nobody offered tail recursion yet? Hey, js is a functional language!

     function r(s) { function r1(s, tail) { return s === '' ? tail : r1(s.substring(1), s[0] + tail); } return r1(s, ''); } 

     function r(s) { function r1(s, tail) { return s === '' ? tail : r1(s.substring(1), s[0] + tail); } return r1(s, ''); } function doit() { $('#r').text( r ($('#i').val()) ); } $(':button').click(doit); doit(); 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input id="i" value="string example"> <br> <button type="button">reverse!</button> <br> Result: <div id="r"> 

      As an option -

       function reverce(string) { var length = string.length == 1 ? 0 : string.length; var result = ''; while (length--) { result += reverce(string[length]); if (length == 0) { string = result; } } return string; } 

      And the test -

       'use strict'; const REPEAT = 5; const ITERATION = 100000; var body = document.getElementsByTagName('body')[0]; function getP(){ return document.createElement('p'); } function runTest(callback){ var repeat = REPEAT; while(repeat-- > 0) { var result = speed(callback); var p = getP(); p.innerHTML = result; body.appendChild(p); console.log(result); } } function speed(callback){ var startTime = new Date(); for (var z = 0; z < ITERATION; z++) { callback(); } var finishTime = new Date(); return 'Время выполнения - ' + (finishTime.getTime() - startTime.getTime()) + '.' } // runTest(); console.log('===== start ====='); var p = getP(); p.innerHTML = '### TEST - 1'; body.appendChild(p); runTest(one); function one(){ repl_str('some text'); function repl_str(str) { if (typeof str == "string") str = { str: str, index: 0, buff: "" }; else if (str.index >= str.str.length) return str.buff; str.buff += str.str.substring(str.str.length - (str.index + 1), str.str.length - str.index); str.index++; return repl_str(str); } } console.log('===== start ====='); var p = getP(); p.innerHTML = '### TEST - 2'; body.appendChild(p); runTest(two); function two(){ repl_str('some text'); function repl_str(str, stack) { if (typeof stack == "undefined") { stack = {}; stack.index = 0; stack.buff = ""; } else if (stack.index >= str.length) return stack.buff; stack.buff += str.substring(str.length - (stack.index + 1), str.length - stack.index); stack.index++; return repl_str(str, stack); } } console.log('===== start ====='); var p = getP(); p.innerHTML = '### TEST - 3'; body.appendChild(p); runTest(three); function three(){ reverce('some text'); function reverce(string) { var length = string.length == 1 ? 0 : string.length; var result = ''; while (length--) { result += reverce(string[length]); if (length == 0) { string = result; } } return string; }; } console.log('================='); 

        Well, or for example

         const reverse = (str) => { let result = ''; for (let i = str.length - 1; i >= 0; i--) result += str[i]; return result; } 
        • one
          Is there a recursion? - αλεχολυτ

        Try this:

         const reverse = a => a.length === 0 ? [] : [ a[a.length - 1], ...reverse(a.slice(0, a.length - 1)) ];