1

I'm trying to add "-" before capital letters. e.g. helloWorld becomes hello-world.

My code, however, is placing the "-" in the array at the wrong places. i.e. thisIsSpinalTap becomes this-I-sSpin-alTap

What's wrong with my code?

function spinalCase(str){
str = str.replace(/ /g,'-');
strArr = str.split("");
for(i=1;i<str.length;i++){
    if(str.charAt(i)==str.charAt(i).toUpperCase()&&str.charAt(i)!=="-"){
        console.log(i);
        strArr.splice(i,0,"-");
    }
} 
return strArr.join("");
}

spinalCase('thisIsSpinalTap'); // returns this-I-sSpin-alTap 
1
  • The issue is that you're looking in str, but modifying strArr and once you've inserted one - character into strArr, the two no longer match indexes properly so you insert in the wrong place. Remember, that .splice() will shift the indexes in strArr. Commented Jul 15, 2015 at 0:46

2 Answers 2

3

What's wrong is that every time you do a splice, strArr drifts to the left; so ideally you should keep another counter that starts at 0 and increases whenever you do another splice, e.g.:

var k = 0;
// ...
    strArr.splice(i + k, 0, '-');
    ++k;

Assuming you're not just doing this to exercise, this is a much easier way:

var s = 'thisIsSpinalTap';

var res = s.replace(/([a-z])([A-Z])/g, '$1-$2'); // "this-Is-Spinal-Tap"

The expression matches a lowercase letter followed by an uppercase letter and then replaces it with a dash in between.

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

Comments

1

The problem here is you are modifying the array in the loop, but you are checking the characters using the string which is not updated based on the new character insertions that happens in the array, so when a - is inserted the indexes in the string will be 1 less that that of the array that is why the - are inserted 1 position less than what is required in the second instance. The same pattern will continue for each insertion so the 3rd insertion will happen at postion-2

function spinalCase(str) {
  str = str.replace(/ /g, '-');
  var strArr = str.split(""),
    i, code;
  for (i = 1; i < str.length; i++) {
    //since we are modifying the array the indexes in the original array can't be used
    code = strArr[i].charCodeAt(0);
    if (code >= 65 && code <= 90) {
      strArr.splice(i, 0, "-");
      //since we are inserting a new element before current element we need to skip an extra element
      i++;
    }
  }
  return strArr.join("");
}

var result = spinalCase('thisIsSpinalTap');
snippet.log(result)
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

2 Comments

Since the for loop goes to str.length and strArr is getting modified to be longer than that, I think there are still issues here. Probably the for loop should go to strArr.length.
@jfriend00 I think the comments in the code does that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.