5

I wrote a JS constructor which reverse a string variable:

function ReverseString(string) {
    this.str = string;
    var size = this.str.length;
    this.reverse = function () {
        for(size; size >= 0; --size) {
            console.log(this.str[size]);
        }
    }
}

When I invoke a reverse method on a new string object("asd") it produces the following output:

  undefined 
    d 
    s 
    a

Where this undefined came from? Could you help me eliminate this ?

4
  • 4
    The range of characters indexes in a string goes from zero to the string length, minus one. Commented Sep 29, 2014 at 12:43
  • 4
    Also, just in case you don't want to reinvent the wheel, str.split("").reverse().join("") is an useful idiom. Commented Sep 29, 2014 at 12:44
  • Just curious, any particular reason you're inventing an entirely new type of object ReverseString with a single purpose in life which is to reverse the string it holds? You plan to reverse it again and again? Commented Sep 29, 2014 at 12:47
  • 3
    Let's see, you searched for "reverse string javascript" before posting this question and found nothing, I guess. Seems no-one ever had this problem before. Except stackoverflow.com/questions/1611427/…, stackoverflow.com/questions/4859208/… (see duplicate answer below), and off-site resources such as eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript. Commented Sep 29, 2014 at 12:53

8 Answers 8

7

The length problem is already explained. To solve it you could use:

function ReverseString(string) {
    this.str = string;
    var size = this.str.length;
    this.reverse = function () {
        while(size--) {
            console.log(this.str[size]);
        }
    }
}

Another (more simple way) to reverse a string is to split it into an array, reverse that, and join again:

somestring.split('').reverse().join('');

Applied to your method, something like this snippet:

const result = document.querySelector('#result');
const RString = stringFactory();

// constructor
const myReversed = new ReverseString('hello world');
myReversed.reverse();

// factory
result.textContent += ` | `;
RString(`Hello World`).printReversed(result);

function ReverseString(string) {
  this.str = string;
  this.reverse = function() {
    const rev = this.str.split('').reverse();
    rev.forEach(v => result.textContent += v);
    this.reversed = rev.join('');
  };
}

// factory pattern
// see also https://github.com/KooiInc/es-stringbuilder-plus
function stringFactory() {
  return str => assignHelpers(str);
  
  function assignHelpers(str) {
    return {
      get reverse() { return str.split('').reverse().join(``); },
      printReversed(elem) {
        str.split('').reverse().forEach( l => 
          elem.textContent += l );
      }
    };
  }
}
#result {
  letter-spacing: 0.5rem;
  font-size: 1.3rem;
  font-weight: bold;
}
<div id="result"></div>

To circumvent the problem @Mark Baijens commented on (combined Unicode characters, aka surrogate pairs), a modern solution (es20xx) could be:

const str = `foo 𝌆 bar mañaña`;
document.querySelector(`#result`)
  .textContent = [...str].reverse().join(``);
#result {
  letter-spacing: 0.5rem;
  font-size: 1.3rem;
  font-weight: bold;
}
<div id="result"></div>

Sign up to request clarification or add additional context in comments.

1 Comment

Warning: This implementation will not work with combined Unicode characters. See this post for an explanation about this.
3

What about this easy step

"hello world".split(' ').map(word=>word.split('').reverse().join('')).join(' ')

it will reverse every word in its place

"olleh dlrow"

1 Comment

You seem to have left out the actual reversing step: "hello world".split(' ').map(word=>word.split('').reverse().join('')).join(' ')
3

Try as altenrative

[...str].reverse().join``;

In your solution size at beginning should be length -1. You mix string reversing with string printing, but you can separate it as follows

let str = "Hello World!";
let r = [...str].reverse().join``;
console.log(r);

Comments

2

At the beginning, size is going to be 3 (the length). There is nothing at index 3, hence undefined. You need to initiate it at length-1.

var size = this.str.length - 1;

3 Comments

I think a better idea would be to either fix the condition in the loop or give the variable a different name. I don't like the idea of a variable named size which isn't actually the size (length) of the string.
I agree that size isn't the best name, but names aren't the most important thing. The logic is. Good names help though, of course.
A variable called size that isn't actually the size of something sounds pretty illogical to me.
2

Here are three ways to reverse a string in JavaScript.

Iterate through string in reverse order and push letters to array, then join the array:

function reverse1(str) {
  if(!str || str.length < 2 || typeof str !== "string") {
    return new Error("Not a valid input");
  }
  const backwards = [];
  for (let i = str.length; i > -1; i--) {
    backwards.push(str[i]);
  }
  return backwards.join('');
}

Use split, reverse, and join methods:

function reverse2(str) {
  return str.split().reverse().join();
}

Use ES6 arrow function and spread operator to copy as well as convert the string to array and then reverse and join:

reverse3 = str => [...str].reverse().join('');

Call the three functions:

console.log(reverse1("Hello World!"));
console.log(reverse2("Hello World!"));
console.log(reverse3("Hello World!"));

Output

!dlroW olleH
Hello World!
!dlroW olleH

1 Comment

reverse2 (as even your Output shows) doesn't work because you haven't specified arguments for splitting and joining. function reverse2(str) { return str.split().reverse().join(); }
1

User recusrsivity, easiest way to do it

function reverse(str){
     if (str.length == 0){ 
        return '';
     }
     return reverse(str.slice(1)) + charAt(0);
}

4 Comments

Instead of str.substring(1, str.length), just str.slice(1). You're also missing parens around your if clause.
I don't think the OP was looking for an alternative implementation but was rather asking why their implementation gave some unexpected results.
Thanks, changed :) I'm doing delphi at the moment used to write with no parens x)
@MattBurland Yup, just giving another solution faster to write. recusrsivity can be usefull :3
1

I would use reduceRight:

function sum(arr) {
    return arr.reduceRight(function(result, chr) {
        return result += chr;
    });
}

Now I have a handy routine I can also use to sum up sequences of numbers (in reverse order, but that doesn't matter).. For string:

function reverse_string(str) {
    return sum(str.split(''));
}

Comments

0

In here you have get the size of the 'string' constructor parameter and you decrese the length of the given word('size' variable).

function ReverseString(string)     { 
    this.str = string; 
    var size = this.str.length;
    this.reverse = function () {
        for(size; size >= 0; --size){ //loop from index value 3 to 0 
          console.log(this.str[size]);
        } 
    }
}

But the problem is when you input word 'asd', the length of that string is 3. So, when you access the index of str[3] should be undefined. Because,

    index[0] --> a
    index[1] --> s
    index[2] --> d
    index[3] --> undfined

So, your code should change,

function ReverseString(string)   { 
    this.str = string; 
    var size = this.str.length; 
    this.reverse = function () {
        for(size; size > 0; --size) { //loop from index value 2 to 0 
            console.log(this.str[size - 1]);
        } 
    }
}

So, output should be like this,

    index[0] --> a
    index[1] --> s
    index[2] --> d

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.