11

This looked fairly straightforward to me when I started, but for some reason I'm getting an empty array everytime I try to run the result on codewars. I'm hoping you can help me identify what the problem is.

function alphabetPosition(text) {
  text.split(' ').join('');
  var chari = "";
  var arr = [];
  var alphabet = "abcdefghijklmnopqrstuvwxyz".split('');
  for(var i = 0; i < text.len; i++){
    chari = text.charAt(i).toLowerCase();
    if(alphabet.indexOf(chari) > -1){
      arr.push(alphabet.indexOf(chari));
    }
  }
  return arr;
}
console.log(alphabetPosition("Hello World"));

My idea is to get the text from the parameter then strip out the spaces. I made a variable for my empty array and make an alphabet string that I can later search through. In the for loop, i make each character lowercase, and if the character is found in the alphabet string, its position gets pushed into the array (arr). I appreciate your time.

Praveen Kumar Purushothaman
  • 160,666
  • 24
  • 190
  • 242
Milos
  • 843
  • 4
  • 13
  • 29
  • 1
    `text.len` shouldn't this be `text.length`? – Sirko Jan 02 '17 at 12:44
  • I appreciate all the answers everyone, thank you. The len thing was causing the array issue. Maybe I was thinking of Python instead. – Milos Jan 02 '17 at 13:07
  • @MlowBunjay - One should always check the browser's console for error messages. http://stackoverflow.com/questions/1648582/equivalent-of-firefoxs-error-console-in-other-browsers – Jeremy J Starcher Jan 02 '17 at 13:24

15 Answers15

14

The Kata works with this code. Try with this one:

function alphabetPosition(text) {
  var result = "";
  for (var i = 0; i < text.length; i++) {
    var code = text.toUpperCase().charCodeAt(i)
    if (code > 64 && code < 91) result += (code - 64) + " ";
  }

  return result.slice(0, result.length - 1);
}
console.log(alphabetPosition("The sunset sets at twelve o' clock."));
Praveen Kumar Purushothaman
  • 160,666
  • 24
  • 190
  • 242
8

You need the String#length property

text.length

instead of text.len.

function alphabetPosition(text) {
    var chari,
        arr = [],
        alphabet = "abcdefghijklmnopqrstuvwxyz",
        i;

    for (var i = 0; i < text.length; i++){
        chari = text[i].toLowerCase();
        if (alphabet.indexOf(chari) !== -1){
            arr.push(alphabet.indexOf(chari));
        }
    }
    return arr;
}
console.log(alphabetPosition("Hello World!!1"));

A solution with ES6

function alphabetPosition(text) {
    return [...text].map(a => parseInt(a, 36) - 10).filter(a => a >= 0);
}
console.log(alphabetPosition("Hello World!!1"));
Nina Scholz
  • 351,820
  • 24
  • 303
  • 358
5

First : deleting space
Second : mapping each char with its alphabet rank
Third : test with the string Happy new year

var alphabet = "abcdefghijklmnopqrstuvwxyz".split('');
var alphabetPosition = text => 
  text.split('').map(x => alphabet.indexOf(x) + 1);
console.log(alphabetPosition("happy new year"));
Kraang Prime
  • 9,443
  • 8
  • 55
  • 116
kevin ternet
  • 4,216
  • 2
  • 16
  • 25
  • couple of notes: you may want to lowercase the text string before mapping; indexOf starts from 0, typically letter position in alphabet starts with 1. other then that, nice code – Vladimir M Jan 02 '17 at 12:52
  • @VladimirM : yes it was just a quick answer but you're right. One could also test if char in the string are non-alphabetic with a short Regex – kevin ternet Jan 02 '17 at 13:00
  • I updated to be 1 based array result since that is what the accepted solution is based on. Also got rid of the `Split(' ').Join('')` since all non alphabet chars are skipped anyway. – Kraang Prime Jan 02 '17 at 13:30
2
function alphabetPosition(text) {
  const words = text.toLowerCase().replace(/[^a-z]/g,"");
  return [...words].map(v=> v.charCodeAt() - 96);
}

First we take the text and transform it into lowercase to get rid of the capital letters using text.toLowerCase() and then we do .replace(/[^a-z]/g,"") to replace all the non a-z characters with nothing.

The next step is to spread the string out into an array using [...words] and then mapping it to get the ascii character code of each a-z character.

Since a = 97 and b = 98 etc we will subtract 96 so that we get a = 1 and b = 2 etc (the position of the letters in the alphabet)

Luke_
  • 718
  • 10
  • 22
1

You can make it even easier, by making use of the acii code. Because a = ascii code 97, b = 98 etc. And there is a javascript function String.charCodeAt( n ) which returns the ascii code at a specific function. You only have to alter the offset for capitals (if you want to support them).

function alphabetPosition( text ) {
 var positions = [];
 for ( var i = 0; i < text.length; i++ ) {
  var charCode = text.charCodeAt( i );
  if ( charCode >= 97 && charCode <= 122 ) {
   positions.push( charCode - 96 );
  } else if ( charCode >= 65 && charCode <= 90 ) { // get rid of this if you don't care about capitals
   positions.push( charCode - 64 );
  }
 }
 return positions;
}

var positions = alphabetPosition( 'Hello World' );
console.log(positions);

Checkout this working fiddle

Kraang Prime
  • 9,443
  • 8
  • 55
  • 116
giorgio
  • 9,885
  • 2
  • 27
  • 41
1

This example will return based on a 0 based array, and uses lambda expressions with filter. I recycle the original byte array created by splitting the text passed to the method.

function alphabetPosition(text) {
  var bytes = text.split('');
  var alphabet = "abcdefghijklmnopqrstuvwxyz".split('');
  for (var i = 0, len = text.length; i < len; i++) {
 bytes[i] = alphabet.indexOf(bytes[i].toLowerCase());
  }
  return bytes.filter(n => { if(n > -1) return n; } ).join(' ');
}
console.log(alphabetPosition("Hello World"));

For a 1 based array result Kata Codewars Friendly

function alphabetPosition(text) {
  var bytes = text.split('');
  var alphabet = "abcdefghijklmnopqrstuvwxyz".split('');
  for (var i = 0, len = text.length; i < len; i++) {
 bytes[i] = alphabet.indexOf(bytes[i].toLowerCase()) + 1;
  }
  return bytes.filter(n => { if(n > 0) return n; } ).join(' ');
}
console.log(alphabetPosition("Hello World"));
Kraang Prime
  • 9,443
  • 8
  • 55
  • 116
0

change len to length:

(var i = 0; i < text.len; i++)
// change to
(var i = 0; i < text.length; i++)
SOFe
  • 7,450
  • 4
  • 30
  • 59
Developer
  • 400
  • 3
  • 17
0

You can also use .charCodeAt function:

function alphabetPosition(text) {
    start = "a".charCodeAt(0);
    end = "z".charCodeAt(0);
    res = [];
    for (var i = 0; i < text.length; i++) {
        index = text.charAt(i).toLowerCase().charCodeAt(0);
        if (index >= start && index <= end) {
            res.push(index - start +1); // +1 assuming a is 1 instead of 0
        } else {
            res.push(0); // Or do w/e you like with non-characters
        }
    }
    return res;
}
console.log(alphabetPosition("Hello World"));
deathangel908
  • 6,985
  • 7
  • 38
  • 73
0

You may do something like this;

var alpha = [].reduce.call("abcdefghijklmnopqrstuvwxyz0123456789 .,!",(p,c,i) => (p[c] = i,p),{}),
      str = "Happy 2017 whatever..!",
    coded = [].map.call(str, c => alpha[c.toLowerCase()]);
console.log(coded);
Redu
  • 22,595
  • 5
  • 50
  • 67
0

Here is a much shorter version that does the same:

function alphabetPosition(text){
  return text.split('').map(function(character){ return character.charCodeAt(0) - 'a'.charCodeAt(0) + 1; })
}

console.log(alphabetPosition("Hello World"));
Borre Mosch
  • 3,953
  • 1
  • 18
  • 28
0

This was my solution on CodeWars. Works perfectly ;)

let alphabetPosition = (text) => {
  let str = Array.from(text.toLowerCase().replace(/[^a-z]/g,''));
  let arr = [];
  for (let i = 0; i < str.length; i++) {
     arr.push(str[i].charCodeAt() - 96);
  }
    return arr.join(' ');
}
0

my answer

function alphabetPosition(text) {
  if (text.match(/[a-z]/gi)) {                                        // if text is not emtpty
    let justAlphabet = text.match(/[a-z]/gi).join("").toLowerCase(); //first extract characters other than letters
    let alphabet = "abcdefghijklmnopqrstuvwxyz";
    let a = [];                                                    // Create an empty array
    for (let i = 0; i < justAlphabet.length; i++) {
      a.push(alphabet.indexOf(justAlphabet[i]) + 1);             //and characters index number push in this array
    }
    return a.join(" ");
  } else {
    return "";                                               
  }
}

console.log(alphabetPosition("The sunset sets at twelve o' clock."));
malibil
  • 58
  • 8
0

this one should work

const lineNumberHandler = (arr) => {
    const alphabet = 'abcdefghijklmnopqrstuwxyz';
    return arr.map((el) => `${alphabet.indexOf(el) + 1}:${el}`);
}
0

This may solve the issue too:

 function alphabetPosition(text) {
            const alphabet = 'abcdefghijklmnopqrstuvwxyz'
            const textWithoutSpaces = text.replace(/\s/g, '');
            const numbers = Array.from(textWithoutSpaces).map((letter) => {
                const lowerCaseLetter = letter.toLowerCase();
                const charI = alphabet.indexOf(lowerCaseLetter)+1
                if(charI) return charI
                return null
            })
            const withoutEmptyValues = numbers.filter(Boolean)
            return withoutEmptyValues.join(' ')
        }
0
function alphabetPosition(text) {
  const letters = text.split('')
  const result = letters.map((l, ix) => {
    const code = l.toUpperCase().charCodeAt() - 64
    if (l.length && code > 0 && code <= 26) {
      return code  
    }
  })
  return result.join(' ').replace(/\s+/g, ' ').trim()
}

I like to do "Single Line Responsibility", so in every line you can find only one action.

The return line, delete all multiples spaces.