When building text converters—such as an English-to-Morse-code translator—a common beginner pattern is using parallel arrays: one array holding the original symbols (letters) and another holding their corresponding translations (Morse signals). However, bridging the gap between an input string and these two arrays often leads to compiler errors and logical indexing bugs.

Understanding the Problem

In the original code, two primary issues prevent the translator from working correctly:

  • Index Misalignment: The loop uses a single counter (counter) to iterate through the characters of the input word. Comparing alpha[counter] to letter[counter] checks whether the first letter of your word is 'A', the second letter is 'B', and so on. Instead, you need to search for the character's position within the alphabet array.
  • Type Mismatch (CS0019): The array alpha contains char values, whereas the letter array contains string values. In C#, you cannot directly compare a char to a string with the == operator without converting one of them.

Solution 1: Fixing the Parallel Array Lookup with Array.IndexOf

To use an index from one array to access another, you can search for the current character in the source array using Array.IndexOf(). To avoid type errors, define your alphabet using char[] instead of string[].

using System;

namespace MorseCode
{
    public class Program
    {
        public static void Main()
        {
            Console.Write("What is your word? ");
            string word = (Console.ReadLine() ?? "").ToUpper();

            // Define letters as chars to match the input characters
            char[] letters = new char[] 
            { 
                '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', ' ' 
            };

            string[] morse = new string[] 
            { 
                ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", 
                "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", 
                "..-", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", 
                "...--", "....-", ".....", "-....", "--...", "---..", "----.", "/" 
            };

            foreach (char ch in word)
            {
                // Find the index of the current character in the letters array
                int index = Array.IndexOf(letters, ch);

                if (index != -1)
                {
                    // Use that same index to retrieve the Morse code
                    Console.WriteLine($"{ch}: {morse[index]}");
                }
                else
                {
                    Console.WriteLine($"{ch}: [Character not supported]");
                }
            }
        }
    }
}

Solution 2: The Modern C# Approach (Using a Dictionary)

While parallel arrays work, they are fragile. If one array gets out of sync by just one element, every subsequent lookup will produce incorrect results. In modern C#, the idiomatic, performant, and safe solution for key-to-value mapping is a Dictionary<char, string>.

using System;
using System.Collections.Generic;

namespace MorseCode
{
    public class Program
    {
        // Key-value pairs guarantee clean and safe lookups
        private static readonly Dictionary<char, string> MorseAlphabet = new()
        {
            ['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'] = "----.", [' '] = "/"
        };

        public static void Main()
        {
            Console.Write("What is your word? ");
            string word = (Console.ReadLine() ?? "").ToUpper();

            foreach (char ch in word)
            {
                if (MorseAlphabet.TryGetValue(ch, out string morseCode))
                {
                    Console.WriteLine($"{ch}: {morseCode}");
                }
                else
                {
                    Console.WriteLine($"{ch}: ?");
                }
            }
        }
    }
}

Key Takeaways

  • Array.IndexOf(array, item) lets you find the target position within your lookup array so you can query another array at that specific index.
  • Ensure comparable types match: compare char with char, or convert with ToString() when matching against string[].
  • Prefer Dictionaries over parallel arrays for lookup scenarios to achieve $O(1)$ constant time complexity and maintainable code.