title: JavaScript - Caesar Cipher
body: <p>I know there have been a few posts about Caesar Ciphers in the past, which I have had a look at, but I haven't found an answer which has helped me to solve this kata, hence my post.</p>
  
  <p>The language is JavaScript. I've written 3 tests, 2 of which are passing so far, but the third is not. I tried to use a nested for loop to loop over the alphabet and the str, and compare them, then shift the alphabet index up/down according to whatever the number was, then push that letter into a new array, and return the joined array at the end.</p>
  
  <p>It's working for positive numbers, but not negatives. (I should also point out that I haven't thought of how to handle spaces yet, I just wanted to get it working for single words first, then take it from there, thanks!)</p>
  
  <p>Any pointers in the right direction would be appreciated.</p>
  
  <p><strong>Kata Instructions:</strong></p>
  
  <p>The function caesarCipher should take a string and a number (n) and return a new string with a Caesar cipher applied. A Caesar cipher replaces each plaintext letter with a different one a fixed number of places up or down the alphabet. N represents the number of shifts up or down the alphabet should be applied. It may be negative or positive.</p>
  
  <pre><code>  E.g.
    caesarCipher('hello', 2)
      --&gt; 'jgnnq'
    caesarCipher('hello world!', -3)
      --&gt; 'ebiil tloia!'
  </code></pre>
  
  <p>My tests:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const caesarCipher = require("../katas/caesar-cipher");
  const { expect } = require("chai");
  
  describe.only("caesarCipher", () =&gt; {
    it("returns an empty string when passed an empty string", () =&gt; {
      const alphabet = [
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z"
      ];
      const str = "";
      const num = 2;
      const actualResults = caesarCipher(alphabet, str, num);
      const expectedResults = "";
      expect(actualResults).to.equal(expectedResults);
    });
    it("returns a string with the letters replaced by the number of shifts up the alphabet", () =&gt; {
      const alphabet = [
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z"
      ];
      const str = "hi";
      const num = 2;
      const actualResults = caesarCipher(alphabet, str, num);
      const expectedResults = "jk";
      expect(actualResults).to.equal(expectedResults);
    });
    it("returns a string with the letters replaced by the number of shifts down the alphabet", () =&gt; {
      const alphabet = [
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z"
      ];
      const str = "dog";
      const num = -3;
      const actualResults = caesarCipher(alphabet, str, num);
      const expectedResults = "ald";
      expect(actualResults).to.equal(expectedResults);
    });
  });</code></pre>
  </div>
  </div>
  </p>
  
  <p>My Solution:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>function caesarCipher(alphabet, str, num) {
    const strToArray = str.split("");
    console.log(strToArray);
    const cipheredStr = [];
    for (let i = 0; i &lt; strToArray.length; i++) {
      for (let j = 0; j &lt; alphabet.length; j++) {
        if (strToArray[i] === alphabet[j] &amp;&amp; Math.sign(num) === 1) {
          console.log(Math.sign(num));
          cipheredStr.push(alphabet[(j += num)]);
        } else if (strToArray[i] === alphabet[j] &amp;&amp; Math.sign(num) === -1) {
          console.log(Math.sign(num));
          console.log(alphabet[(j -= num)]);
          cipheredStr.push(alphabet[(j -= num)]);
        }
      }
    }
    console.log(cipheredStr.join(""));
    return cipheredStr.join("");
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>The Results:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>caesarCipher
  []
  
      ✓ returns an empty string when passed an empty string
  [ 'h', 'i' ]
  1
  1
  jk
      ✓ returns a string with the letters replaced by the number of shifts up the alphabet
  [ 'd', 'o', 'g' ]
  -1
  g
  -1
  r
  -1
  j
  jum
      1) returns a string with the letters replaced by the number of shifts down the alphabet
  
  
    2 passing (15ms)
    1 failing
  
    1) caesarCipher
         returns a string with the letters replaced by the number of shifts down the alphabet:
  
        AssertionError: expected 'jum' to equal 'ald'
        + expected - actual
  
        -jum
        +ald
        
        at Context.&lt;anonymous&gt; (spec/caesar-cipher.spec.js:108:30)
        at processImmediate (internal/timers.js:456:21)</code></pre>
  </div>
  </div>
  </p>