Loops help

At the end of the loops interactive lesson, there is a challenge.

Try writing a program that:

Loops through a piece of text and only prints words that start with the letter “a” to the console to create a poem.

Let’s say I want to loop through this text:

“Another One Bites The Dust And Another One Down”

How would I go about doing that? What would I use to select only the words that start with the letter a? I have no clue where to begin. Thanks.

1 Like

Hello, @micro6179079364.

You might start by investigating the String.Split() method. If you could convert your text into an array of words, you could then iterate through that array, and print only the words that begin with “a”. One noteworthy fact: You can access individual characters in a string by index the same way you can access elements of an array. Strings are in actuality arrays of individual characters. For example:

Console.WriteLine("Hello World!"[6]); //prints: W

Hopefully this will help you to get started. If you need more help, feel free to ask. Good luck && happy coding!

2 Likes

Hi, thanks for setting me on the right track. After doing some research on the Googler, I came up with this:

using System;
class LoopsPractice {
  static void Main() {
    
    string[] counter = {"One", "Bites", "The", "Dust", "Down", " "};
    
    string phrase = "Another One Bites The Dust And Another One Down";
    
    string[] words = phrase.Split(counter, System.StringSplitOptions.RemoveEmptyEntries);

    foreach (var word in words)
    {
      Console.WriteLine(word);
    }
  }
}

I had to include " " (quotation marks with one space in between) in the array

string[] counter = {"One", "Bites", "The", "Dust", "Down", " "};

to get rid of the awkward spacing. I’m not sure why it got rid of the awkward spacing but it did it. It went from looking like this:

Another                                                                                                                         
                                                                                                                                
                                                                                                                                
                                                                                                                                
 And Another

to this :

Another                                                                                                                         
And                                                                                                                             
Another 

Zero spaces or any number other than one in between the quotation marks brings back the awkward spacing.

I’m glad I came up with the desired result of printing only the words that started with A, but I cannot help but think there are better ways to do this? How would you do it? Also why is var used here?

foreach (var word in words)

I switched out the word var with the word string and the code still runs fine. Thanks.

You never test for this. That’s not what your code does. It does something else, and that’s also where your strange behaviour comes from.

When you describe what should happen, you do not specifically need to mention the words “One”, “Bites”, “The” … and so on. That wasn’t the requirement.

2 Likes

Oh dear, back to the drawing board I go. Thanks.

2 Likes

Hint: There’s another version of the String.split() method that would be easier for your purpose. If you’re curious, look into what this does:

Hint
      string text = "Another One Bites The Dust And Another One Down";
      string[] textArray = text.Split(' ');
1 Like
One noteworthy fact: You can access individual characters in a string by index the same way you can access elements of an array. Strings are in actuality arrays of individual characters. For example:

Console.WriteLine("Hello World!"[6]); //prints: W

Going back to that, and looking at this :

Hint

      string text = "Another One Bites The Dust And Another One Down";
      string[] textArray = text.Split(' ');

I can see that :

   Console.WriteLine(textArray[0]);  //prints: Another
   Console.WriteLine(textArray[1]);  //prints: One
   Console.WriteLine(textArray[2]);  //prints: Bites
   Console.WriteLine(textArray[3]);  //prints: The
   Console.WriteLine(textArray[4]);  //prints: Dust
   Console.WriteLine(textArray[5]);  //prints: And
   Console.WriteLine(textArray[6]);  //prints: Another
   Console.WriteLine(textArray[7]);  //prints: One
   Console.WriteLine(textArray[8]);  //prints: Down

Index 0 is Another, Index 1 is One, etc.

I’m not sure what to do with this new found information as I’m still unsure as to how I would filter out the words that don’t start with A. I’ll keep looking into it.

What if you applied this logic to the textArray, but instead of printing every word only printed the words that you want?

1 Like

I tried something like this

    foreach (var word in textArray)
    {
      Console.WriteLine(textArray[0]);
      Console.WriteLine(textArray[5]);
      Console.WriteLine(textArray[6]);
    }

but it doesn’t appear to be correct. It’ll repeat the desired result 3 times, I suppose once for each element in the array. I’ve been thinking of ways to make it not repeat but I’m drawing blanks. Or is this supposed to happen?

Edit: I thought I had already tried using BREAK to no avail yesterday but I tried it again today.

using System;
class LoopsPractice {
  static void Main() {
    
    string text = "Another One Bites The Dust And Another One Down";
    
    string[] textArray = text.Split(' ');
    
    //Console.WriteLine(textArray[0]);  prints: Another
    //Console.WriteLine(textArray[1]);  prints: One
    //Console.WriteLine(textArray[2]);  prints: Bites
    //Console.WriteLine(textArray[3]);  prints: The
    //Console.WriteLine(textArray[4]);  prints: Dust
    //Console.WriteLine(textArray[5]);  prints: And
    //Console.WriteLine(textArray[6]);  prints: Another
    //Console.WriteLine(textArray[7]);  prints: One
    //Console.WriteLine(textArray[8]);  prints: Down
    

    foreach (var word in textArray)
    {
      Console.WriteLine(textArray[0]);
      Console.WriteLine(textArray[5]);
      Console.WriteLine(textArray[6]);
      break;
    }
  }
}

I got the desired result again, hopefully this is it.

Isn’t it the program that should be figuring out which words to write out?
I don’t think it’s true that all possible pieces of text has a word at positions 0, 5, 6, and nowhere else.

1 Like

So after you’ve split the words…

> myWords = words "Another One Bites The Dust And Another One Down"
> myWords
["Another","One","Bites","The","Dust","And","Another","One","Down"]

Is it possible to look at the first letters?

> map (take 1) myWords
["A","O","B","T","D","A","A","O","D"]

And determine whether they’re equal to A?

> map (take 1 >>> (=="A")) myWords
[True,False,False,False,False,True,True,False,False]

And from there decide which to keep…

> filter (take 1 >>> (=="A")) myWords
["Another","And","Another"]

And print them out?

> putStr $ unlines $ filter (take 1 >>> (=="A")) myWords
Another
And
Another

Except, in C#, obviously.
Just like I did here, you’d want to start by writing out each word.
Then, see if you can isolate the first character…
compare it to A
do something based on the comparison

After having solved each subproblem, you can make sure it runs and that you have the right information before you move on

1 Like

What if you replace textArray with word in your Console.WriteLine() calls?

1 Like
Is it possible to look at the first letters?

> map (take 1) myWords
["A","O","B","T","D","A","A","O","D"]

Hi thanks, I had been thinking about that. To get the first letter I wanted to use substring like this:

    string index0 = textArray[0].Substring(0,1);
    Console.WriteLine(index0);
    
    string index1 = textArray[1].Substring(0,1);
    Console.WriteLine(index1);
    
    string index2 = textArray[2].Substring(0,1);
    Console.WriteLine(index2);
    
    string index3 = textArray[3].Substring(0,1);
    Console.WriteLine(index3);
    
    string index4 = textArray[4].Substring(0,1);
    Console.WriteLine(index4);
    
    string index5 = textArray[5].Substring(0,1);
    Console.WriteLine(index5);
    
    string index6 = textArray[6].Substring(0,1);
    Console.WriteLine(index6);
    
    string index7 = textArray[7].Substring(0,1);
    Console.WriteLine(index7);
    
    string index8 = textArray[8].Substring(0,1);
    Console.WriteLine(index8);

Then after that I would use an if statement to compare like this

    if (index0 == "A") {
      Console.WriteLine("Another");
    }

That’s all I have so far

Your code shouldn’t be mentioning any knowledge about the string. It shouldn’t mention the word “Another” because that might not be in the string. It should not mention specific locations, because you don’t know which locations exist.

You can only mention things that come directly from the requirement: “first letter”, “equal to a?”, that’s all you know.

1 Like

If I did this:

    foreach (var word in textArray)
    {
      Console.WriteLine(word[0]);
      

I would get the first letter of each element without having to use substring.

2 Likes

:bulb: Now you’re making progress! :+1:

2 Likes

Hello everyone. I just tried this exercise and thanks to this topic and a bit of googling, I figured it out!
I still have a few small things I wanted to ask. This is my code:

using System;

namespace LoopsReview
{
  class Program
  {
    static void Main(string[] args)
    {
      string text = "An amazing butterfly. Soaring through the sweet summer air. He is looking for the kingdom of apples.";
      string[] words = text.Split(" ");
      foreach (string word in words)
      {
      if (word[0] == 'a')
      {
        Console.WriteLine(word);     
      }
      else if (word[0] == 'A')
      {
        Console.WriteLine(word);
      }
      }
    }
  }
}

My first question is how I can only get the words and leave things like dots and comma’s out. In my version here the words air and apples are printed like “apples.” and “air.” in the console.
Second question: I wrote an if and if else statements. One checks for the lower case letter ‘a’ and the other checks for the upper case letter ‘A’. Is there any shortcut how I can check for both uppercase and lower case at the same time? Any other feedback is highly appreciated since I just started learning to code with this website 4 days ago.

Thanks in advance!

P.S I am new to the website and have really been enjoying it and learning a lot :slight_smile:

Hello, @micwini.

Welcome to the forums!

Check out the methods I added to your code below. Google the unfamiliar methods (ie. Char.ToLowerInvariant(), TrimEnd()) for more information, and feel free to ask questions.

    static void Main(string[] args)
    {//declaring variables
      string text = "An amazing butterfly. Soaring through the sweet summer air. He is looking for the kingdom of apples.";
      string[] words = text.Split(" ");
      char[] charsToTrim = {'.', ',', ';', '!', '?'};
      foreach (string word in words)
      {
        if (Char.ToLowerInvariant(word[0]) == 'a')
        {
          Console.WriteLine(word.TrimEnd(charsToTrim));    
        }
      }
    }

By converting the letter at word[0] to lowercase before comparing, we eliminate the need to compare to the uppercase A. We aren’t converting the letter to lowercase permanently. We are only comparing the lowercase equivalent of the letter (char). Happy coding!!

Hello, thanks for your help :slight_smile:
It works exactly as I wanted to now!

I only had one question: In the if statement, “Char.ToLowerInvariant…”
Where does the “Char” come from? Or is that part of the built in method?

1 Like

https://docs.microsoft.com/en-us/dotnet/api/system

1 Like