Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For statement returns unexpected value on last assignment

Tags:

javascript

I'm trying to build a simple "cipher" to assign the letters in a string the value of a reversed alphabet (e.g. a=z b=y, etc..) I built a for statement that seems to work until the last call and instead of giving the reversed value instead gives the original value.

I commented out each line in the for statement and then worked through them one at a time to check their returns. The second to last statement (c = rev.indexOf(c);) give the value of 25, 24, 23 (as expected) so I don't understand why when it looks them up in the "letters" matrix it gives a return of a, b, c instead of z, y, x.

var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'y', 'x', 'z'];
var rev = letters.reverse();

var stringy = function(n){
    ns = n.split("");
    for (i = 0; i < n.length; i++){
            c = ns[i];
            c = rev.indexOf(c);
            c = letters[c];
            console.log(c);
    }
}

stringy("abc");
like image 366
oneWorkingHeadphone Avatar asked Dec 01 '25 17:12

oneWorkingHeadphone


2 Answers

letters.reverse() doesn't just return the reversed array. It reverses the array in place.

If you check the contents of letters after letters.reverse() you'll see that the order has been reversed.

You can use .slice() to make a copy of the array, which you can then reverse:

var rev = letters.slice().reverse();
like image 82
zzzzBov Avatar answered Dec 04 '25 07:12

zzzzBov


As an addition to zzzzBov information to the Array.reverse() method, I thought I would add an answer that doesn't require reversing your letters. There is no need to keep 2 variables just to reverse them based on the index, just find the index in the letters array and search from the end of the letters array back.

I added a slightly modified version of your code, to show how you could make it yourself a bit easier and added some code comments where I thought appropriate

// make your debugging easier
'use strict';

var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'y', 'x', 'z'];

var getReversedCypher = function( text, sequence, unmatched ) {
  if (!text) {
    return '';
  }
  var ns = text.split(''),
      cypher = [], 
      lastLetterIndex = sequence.length - 1;
  
  // use strict adds forEach on arrays
  ns.forEach(function(char) {
    var index = sequence.indexOf(char);
    if (index < 0) {
      // couldn't find a match, you could throw an error, I chose to add an extra character
      cypher.push( unmatched || '-' );
    } else {
      // no need to use a reversed lookup, just search the table from the end
      cypher.push( sequence[lastLetterIndex-index] );
    }
  });
  return cypher.join('');
};

// make some utility methods to still use your simple function
var encode = function( text ) {
  return getReversedCypher( text, letters, '-' );
};

var decode = function( text ) {
  return getReversedCypher( text, [].concat(letters).reverse(), ' ' );
};
    
var encoded = encode("this is the sound of speech"), decoded = decode(encoded);

console.log('cypher: ' + encoded);
console.log('decoded: ' + decoded);
like image 23
Icepickle Avatar answered Dec 04 '25 07:12

Icepickle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!