HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Getting the index of a character within the alphabet

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
alphabetthecharactergettingwithinindex

Problem

I've made this function to map alphabetic coordinates to their corresponding ordinal number.



`var exec = document.querySelector('#exec');

// Maps alphabetic characters to their index
// within the alphabet.
// --------------------------------------------
// @param { string || array } chars - String
// consisting of a single alphabetic character
// or an array which elements are single
// alphabetic characters.
// @throws Error in case of invalid
// parameter ( == not a single alphabetic
// character ).
// --------------------------------------------
// @returns { array } with numbers. The indexes
// of the characters within the alphabet.
//
// ------- Usage examples ----------
// getIndexInAlphabet('i')); // Result : [9]
// getIndexInAlphabet(['a', 'B', 'c'])[1] // 2
// getIndexInAlphabet(['a', 'G', 'z'])); // [1, 7, 26]

function getIndexInAlphabet( chars ) {
var 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' ];

if (!Array.isArray(chars)) {
if (typeof chars === 'string') {
let tmp = [];
tmp.push(chars);

chars = tmp;
} else {
throw new Error(
'Parameter invalid because not of type string.');
}
}

chars.forEach(function(item, i) {
if (typeof item !== 'string') {
throw new Error('Element ' + i +
' invalid because not of type string.');
}
});

return chars.map(function(char, i) {
var ret = alphabet.indexOf(char.toLowerCase()) + 1;

if (ret === 0) {
throw new Error('Element ' + i + ' invalid because' +
' not an alphabetic character.');
}

return ret;
});
}

// -- From here on : Just testing ...
exec.addEventListener('click', function() {
try {
console.log(getIndexInAlphabet(['a', 'B', 'c'])[1])
console

Solution

The alphabet would be simpler if it were written as a string, and it should be const. I'd also name it ALPHABET to emphasize that it is constant.

Using three statements to stuff a string into an array is too cumbersome. In my opinion, there is not much value in verifying that a non-array parameter is a string, since you'll validate each element of the array anyway. Does it really matter that the error message is slightly different?

The validation of each array element can be rolled into the map callback. In keeping with JavaScript's duck-typing philosophy, I would check that it has a .toLowerCase() method, rather than that it is of type string.

I find it weird that the function returns an array even if the input is a single character. I suggest renaming the function to getIndexesInAlphabet to make it clear that it returns an array.

function getIndexesInAlphabet(chars) {
  const ALPHABET = 'abcdefghijklmnopqrstuvwxyz'.split('');

  if (!Array.isArray(chars)) {
    chars = [chars];
  }

  return chars.map(function(char, i) {
    if (!char.toLowerCase) {
      throw new Error('Element ' + i +
                      ' invalid because it is not a string.');
    }

    var ret = ALPHABET.indexOf(char.toLowerCase()) + 1;

    if (ret === 0) {
      throw new Error('Element ' + i + ' invalid because' +
                      ' not an alphabetic character.');
    }

    return ret;
  });
}


Also consider whether you really want to accept arrays at all. Unless you plan to be able to support spreadsheet-style coordinates (e.g. AA to represent column 27), every coordinate will be a single character. You could rationalize the interface by accepting only strings:

// Maps alphabetic characters to their 1-based index within the alphabet. 
// --------------------------------------------  
// @param { string } chars - String
//  consisting of a one or more alphabetic characters.
// @throws Error if the input contains a non-alphabetic character.
// --------------------------------------------  
// @returns { array } with 1-based indexes. The indexes
//  of the characters within the alphabet.
// 
// ------- Usage examples ----------
// getIndexesInAlphabet('i'); // Result : [9]
// getIndexesInAlphabet('aBc')[1] // 2
// getIndexesInAlphabet('aGz'); // [1, 7, 26]      
function getIndexesInAlphabet(chars) {
  const ALPHABET = 'abcdefghijklmnopqrstuvwxyz';

  return chars.split('').map(function(char, i) {
    var index = ALPHABET.indexOf(char.toLowerCase());
    if (index < 0) {
      throw new Error(char + 'is not a valid alphabetic character.');
    }
    return index + 1;
  });
}


If what is passed is not a string, it would be standard JavaScript programming practice not to bother trying to make sense of it or throwing a custom error.

Code Snippets

function getIndexesInAlphabet(chars) {
  const ALPHABET = 'abcdefghijklmnopqrstuvwxyz'.split('');

  if (!Array.isArray(chars)) {
    chars = [chars];
  }

  return chars.map(function(char, i) {
    if (!char.toLowerCase) {
      throw new Error('Element ' + i +
                      ' invalid because it is not a string.');
    }

    var ret = ALPHABET.indexOf(char.toLowerCase()) + 1;

    if (ret === 0) {
      throw new Error('Element ' + i + ' invalid because' +
                      ' not an alphabetic character.');
    }

    return ret;
  });
}
// Maps alphabetic characters to their 1-based index within the alphabet. 
// --------------------------------------------  
// @param { string } chars - String
//  consisting of a one or more alphabetic characters.
// @throws Error if the input contains a non-alphabetic character.
// --------------------------------------------  
// @returns { array } with 1-based indexes. The indexes
//  of the characters within the alphabet.
// 
// ------- Usage examples ----------
// getIndexesInAlphabet('i'); // Result : [9]
// getIndexesInAlphabet('aBc')[1] // 2
// getIndexesInAlphabet('aGz'); // [1, 7, 26]      
function getIndexesInAlphabet(chars) {
  const ALPHABET = 'abcdefghijklmnopqrstuvwxyz';

  return chars.split('').map(function(char, i) {
    var index = ALPHABET.indexOf(char.toLowerCase());
    if (index < 0) {
      throw new Error(char + 'is not a valid alphabetic character.');
    }
    return index + 1;
  });
}

Context

StackExchange Code Review Q#130011, answer score: 4

Revisions (0)

No revisions yet.