2015-05-21 11 views
7

Sto tentando di imparare Javascript leggendo un sacco di tutorial online e mi sto esercitando lavorando attraverso le sfide su coderbyte. Sto avendo problemi con la sfida CaesarCipher. La funzione deve prendere una stringa e un parametro di offset e quindi restituire la stringa con ogni carattere alfa spostato dall'offset fornito (lasciando intatti tutti i caratteri non alpha). Ho la mia funzione shiftChar() funzionante, che prenderà il carattere e l'offset e applicherà lo spostamento solo per caratteri alfa e restituirà il nuovo carattere. Ora che è completo, ho pensato che sarei stato in grado di prendere semplicemente la stringa originale, dividerla in un array e quindi mappare quella matrice di caratteri in un nuovo array usando la mia funzione shiftChar(). Tuttavia, non riesco a farlo funzionare e non riesco a capire perché.Caesar Cipher in Javascript utilizzando la funzione shiftChar() e il metodo Array.map()

C'è qualcosa che mi manca del metodo della mappa? La mia comprensione è che il metodo map passerà automaticamente ogni elemento nell'array su cui è chiamato come primo argomento. Quindi sto solo passando il mio valore di offset come argomento aggiuntivo. Qualcuno può per favore chiarire perché questo non funziona e suggerire un approccio più funzionale?

/* 
Using the JavaScript language, have the function CaesarCipher(str,num) take the str parameter and perform a Caesar Cipher shift on it using the  num parameter as the shifting number. A Caesar Cipher works by shifting each letter in the string N places down in the alphabet (in this case N will be num). Punctuation, spaces, and capitalization should remain intact. For example if the string is "Caesar Cipher" and num is 2 the output should be "Ecguct Ekrjgt". 
*/ 

var str = 'Caesar Cipher'; 

function CaesarCipher(str, offset){ 
    var charArray = str.split(''); 
    var result = charArray.map(shiftChar(char, offset)).join(''); 

    function shiftChar(char, offset){ 
    var isAlpha = /[A-z]/; 

    if(isAlpha.test(char)){ 
     char = String.fromCharCode(char.charCodeAt(0) + offset); 
     if(char > 'Z' && char < 'a' || char > 'z') 
     char = String.fromCharCode(char.charCodeAt(0) - 26); 
    } 
    return char; 
    } 
    return result; 
} 

console.log(CaesarCipher(str, 2)); 

risposta

2

Ci sono alcune cose nel codice che ti impediscono di ottenere i risultati desiderati.

Array.map() restituisce un array, non modifica l'array originale. Nell'esempio si memorizza il nuovo array in result, ma la funzione restituisce l'originale charArray e non result, che è ciò che si desidera.

Il secondo problema è la funzione di richiamata che si sta fornendo a map. Il primo argomento della mappa dovrebbe essere una funzione, ma shiftChar(char, offset) non è una funzione, è il risultato della chiamata shiftChar. (Spero che questa parte abbia un senso). In genere quando si lavora con map, si crea una funzione anonima che riceverà gli argomenti specificati nella documentazione seguente. Nel tuo caso, si vorrebbe effettuare le seguenti operazioni:

var result = charArray.map(function(char) { return shiftChar(char, offset); }).join(''); 

Array.map di riferimento: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

piena esempio jsfiddle: http://jsfiddle.net/p2fkLs2t/

+1

Ah, questo era esattamente il mio problema, e questa spiegazione aiuta totalmente a chiarire la mia comprensione. Intendevo restituire il risultato, e non charArray come nel mio codice originariamente inviato. In precedenza avevo restituito il risultato e poi l'ho cambiato in charArray per controllare il valore e ho dimenticato di cambiarlo. Il secondo paragrafo è fondamentale per me: è perfettamente logico che shiftChar (char, offset) non sia una funzione, ma un qualsiasi valore venga restituito da quella chiamata di funzione. Capisco la distinzione ma sono appena scivolato. Credo che ci sia bisogno di un po 'più di pratica prima che il concetto affondi.Grazie! – tbutman

-1

Questo dovrebbe funzionare:

var str = 'Caesar Cipher'; 

function CaesarCipher(str, offset){ 
    var charArray = str.split(''); 

    function shiftChar(char){ 
    var isAlpha = /[a-z]/i; 

    if(isAlpha.test(char)){ 
     char = String.fromCharCode(char.charCodeAt(0) + offset); 
     if(char > 'Z' && char < 'a' || char > 'z') 
     char = String.fromCharCode(char.charCodeAt(0) - 26); 
    } 
    return char; 
    } 

    var result = charArray.map(shiftChar).join(''); 

    return result; 
} 

console.log(CaesarCipher("test", 2)); 
2

Se è necessario parametrizzare la funzione shiftChar quando si mappa sopra la matrice, è possibile al curry in modo che ci vuole un parametro alla volta:

function shiftChar(offset) { 
    return function(char) { 
     var isAlpha = /[a-z]/i; 

     if(isAlpha.test(char)){ 
      char = String.fromCharCode(char.charCodeAt(0) + offset); 
      if(char > 'Z' && char < 'a' || char > 'z') 
      char = String.fromCharCode(char.charCodeAt(0) - 26); 
     } 
     return char; 
    } 
} 

modo che ci si deve chiamare come shiftChar(22)('a') di spostare la lettera "a" di 22.

Questo ti permette di fare "Hello".split("").map(shiftChar(22));.

+0

Questo funziona, o si può semplicemente passare una funzione anonima a 'map' –

Problemi correlati