Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Morse code converter

I am writing a basic morse code converter in PHP which can take a string and convert it into morse code. It is using an associative array, a foreach loop, and a for loop. It works, except for some reason it outputs the morse code equivalent for '0' after each converted character. I can't figure out where the 0 is coming from. If I remove 0 from the associative array, there is no problem but I want to be able to convert numbers as well. If anyone is able to give me some feedback, that would be much appreciated.

Here is the code:

<?php
$string = "dog";
$string_lower = strtolower($string);
$assoc_array = array(
    "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"=>"--..", 
    "0"=>"-----",
    "1"=>".----", 
    "2"=>"..---", 
    "3"=>"...--", 
    "4"=>"....-", 
    "5"=>".....", 
    "6"=>"-....", 
    "7"=>"--...", 
    "8"=>"---..", 
    "9"=>"----.",
    "."=>".-.-.-",
    ","=>"--..--",
    "?"=>"..--..",
    "/"=>"-..-.",
    " "=>" ");
    for($i=0;$i<strlen($string_lower);$i++){
        foreach($assoc_array as $letter => $code){
            if($letter == $string_lower[$i]){
                echo "$code<br/>";
            }
        }
    }
?>
like image 978
8se7en Avatar asked Mar 22 '16 09:03

8se7en


2 Answers

The main issue is that you are doing "more" than necessary. There is no need to loop through your $assoc_array like that when you can use the string to fetch the needed data from it.

This also uses less resources, as instead of looping from a-z and 0-9 you only loop the exact amount of letters / numbers / spaces required.

/*Rest of your code above*/
for($i=0;$i<strlen($string_lower);$i++){
    echo (isset($assoc_array[$string_lower[$i]])) ? $assoc_array[$string_lower[$i]] . '<br />' : 'ERROR';       
} 

Since your array contains everything from a-z and 0-9 you can easily just call the required letters without worrying about missing data.

Edit: Added a isset() check, it will hardly be needed as the $assoc_array covers every needed letter / number, but better safe than sorry. (Credit to @Farkie for reminding me)

like image 62
Epodax Avatar answered Sep 30 '22 03:09

Epodax


The simplest fix is simple to add a 'break' after the echo:

foreach($assoc_array as $letter => $code){
                if($letter == $string_lower[$i]){
                        echo "$code<br/>";
                        break;
                }
        }

The real problem is that the 0 is evaluating to false, which means that when it's looping over it, it's going to be a truthy (false == false).

You can solve it even better by doing an identical (===) match:

foreach($assoc_array as $letter => $code){
                if($letter === $string_lower[$i]){
                        echo "$code<br/>";
                        break;
                }
        }
like image 31
Farkie Avatar answered Sep 30 '22 03:09

Farkie