6

I tried Googling this but not sure what's the best thing to look for. What I am trying to do is to translate a text input to output the letters of a touch tone phone. For example Hello World would output 43550 96153the idea is I'm trying to use the tropo voice api system and want the user to be able to enter their name as touch tone values and match that to their name as numbers in my database.

I'm assuming this can be done with a function along the lines of

$input= $touchtone_value;  
$number_two_array (a,b,c);  
if( $input==in_array($number_two_array)){ 
        $output = '2';
}

I'm sure this will work. However, if there is a class out there or a simpler function than to break each letter into number arrays I think that would be a better way to do it. At this point this is a fairly open ended question as I have NO IDEA where to start as the best way to accomplish this.

EDIT: I found a solution, not sure it's the best one.

            $input = strtolower('HELLO WORLD');
            echo  'input: '. $input. "\n";
            echo $output = 'output: '.  strtr($input,'abcdefghijklmnopqrstuvwxyz', '22233344455566677778889999'); 

input:hello world 
output: 43556 96753

Now I just need to find a way to remove white space :) http://codepad.org/Ieug0Zuw

Source: code a number into letters

Community
  • 1
  • 1
Brooke.
  • 3,691
  • 13
  • 49
  • 80

3 Answers3

3

PHP provides a function called strtr which does string translations. The first argument is what you want to translate, the second is the original characters, the third is the replacement characters. Below is a function that should do what you want. Edit: Updated my sample to strip out any characters that aren't supported (anything other than a-z or a space)

<?php

function get_tones($inp) {
    $from = 'abcdefghijklmnopqrstuvwxyz ';
    $to = '222333444555666777788899990';

    // convert the input to lower case
    $inp = strtolower($inp);

    // remove anything that isn't a letter or a space
    $inp = preg_replace('/[^a-z ]/', '', $inp);

    return strtr($inp, $from, $to);
}

assert(get_tones('Hello world') == '43556096753');
assert(get_tones('Hell234"*&o world') == '43556096753');
assert(get_tones('ALEX') == '2539');
assert(get_tones('    ') == '0000');
Alex Vidal
  • 4,080
  • 20
  • 23
  • Thanks, See above I updated the question to include this example before you posted this :P – Brooke. Mar 02 '11 at 22:03
  • @BandonRandon: Yeah, I noticed that myself after I posted it. I actually had a solution using arrays like the other answer, but realized that `strtr` is smaller, cleaner, much more readable, and any performance differences are going to be negligible. – Alex Vidal Mar 02 '11 at 22:06
  • what's the best way to strip spaces? I know I can remove the space and 0 from the end of the strings but isn't there a simple regex that can be used in `preg_replace`? – Brooke. Mar 03 '11 at 20:39
  • Sorry, feel stupid now didn't see the space at the end of `/[^a-z ]/` if I use `[^a-z]` problem solved :) – Brooke. Mar 03 '11 at 20:52
2

How about a structure like this... NOTE: This will ignore invalid 'letters' like spaces, punctuation, etc..

LIVE DEMO http://codepad.org/pQHGhm7Y

<?php
    echo getNumbersFromText('Hello There').'<br />';
    echo getNumbersFromText('This is a really long text string').'<br />';

    function getNumbersFromText($inp){
        $result=array();
        $inp = strtolower($inp);
        $keypad = array('a' => '2', 'b' => '2', 'c' => '2', 'd' => '3',
            'e' => '3', 'f' => '3', 'g' => '4', 'h' => '4',
            'i' => '4', 'j' => '5', 'k' => '5', 'l' => '5',
            'm' => '6', 'n' => '6', 'o' => '6', 'p' => '7',
            'q' => '7', 'r' => '7', 's' => '7', 't' => '8',
            'u' => '8', 'v' => '8', 'w' => '9', 'x' => '9',
            'y' => '9', 'z' => '9');

        for ($x=0; $x<strlen($inp); $x++){
            $letter = $inp[$x];
            if ($keypad[$letter]) $result[]= $keypad[$letter];
        }
        return implode('',$result);
    }
?>
Dutchie432
  • 28,798
  • 20
  • 92
  • 109
  • Thanks, is this going to be faster than the solution I found above? Seems like it may be more work but I don't know how much resources `strtr` uses – Brooke. Mar 02 '11 at 21:54
  • Both methods essentially accomplish the same thing. In your example, you're creating two arrays (one for the numbers and one for the letters) with corresponding indices. In my method, I am creating a single array where the `key` is the letter and the `value` is the letter. In all honesty, my method may be a bit faster because I am calling the array item by index, and I do not need to search the array, as the `strtr()` function probably does. – Dutchie432 Mar 02 '11 at 21:57
  • @Dutchie432 Thanks for the explanation. Another thing I like about yours is that it gets rid of all invalid characters which is always a plus. :) Thanks! – Brooke. Mar 02 '11 at 22:01
  • 1
    @Dutchie432: I made a simple benchmark (which very well could be wrong) testing both your solution and the `strtr` method against 4 strings, 10,000 times each, and it looks like your solution is about an order of magnitude slower than the `strtr` method. See: http://codepad.org/uogSa8TO – Alex Vidal Mar 02 '11 at 22:16
  • Note about the benchmark: These functions are very trivial and both implementations are good enough. The benefit to `strtr` is that it's simpler to read and understand. – Alex Vidal Mar 02 '11 at 22:17
  • @Alex Vidal: Fair enough. This is just how I would have done it and did not run any tests. Appreciate the effort. +1 – Dutchie432 Mar 02 '11 at 22:55
  • @Dutchie432: Without doing real analysis, I'd wager that you can improve yours easily in at least two ways: Convert the entire input to lowercase in the beginning, instead of char by char; and build the output as an array and join it at the end instead of using string concatenation. **edit** I just did this change myself on that benchmark script and it didn't improve any. I'm guessing `strtr` is backed by C code. – Alex Vidal Mar 02 '11 at 22:58
  • I just ran a test using the code in my edit as the whole array as a single `strtr` and it is slower that the `get_tones` method http://codepad.org/ads70etk – Brooke. Mar 03 '11 at 20:48
1

I'm not sure I understand exactly what you are asking:

  1. Your input is words, and you want to output the corresponding numbers?
  2. Your input is numbers, and you want to output the corresponding words?

In case (1), it's simple, just use an array that maps each letter of the alphabet to the corresponding numbers (i.e. key is letter, value is number). You can then just iterate over the characters of the input, and output using the corresponding element in the array.

Case (2) is a bit trickier. You can build a Trie from your list of names, and use it to do the lookup.

mfonda
  • 7,873
  • 1
  • 26
  • 30