🐥

Add Logic to C# Console Applications のメモ

2024/03/13に公開

この記録は、以下の freeCodeCamp の学習コンテンツのメモになります。

三項演算子での課題

/*
2. Use the Random class to generate a value.
Consider the range of numbers that is required.

3. Based on the value generated, use the conditional operator to display either heads or tails.
There should be a 50% chance that the result is either heads or tails.

4. Your code should be easy to read, but with as few lines as possible.
You should be able to accomplish the desired result in three lines of code.

*/
Random coin = new Random();
int result = coin.Next(0, 2);
Console.WriteLine($"{(result == 0 ? "heads" : "tails" )}");

まとめの課題

https://learn.microsoft.com/en-us/training/modules/csharp-evaluate-boolean-expressions/6-challenge-2

/*

1. If the user is an Admin with a level greater than 55, output the message:

Output
---
Welcome, Super Admin user.
---

2. If the user is an Admin with a level less than or equal to 55, output the message:

Output
---
Welcome, Admin user.
---

3. If the user is a Manager with a level 20 or greater, output the message:

Output
---
Contact an Admin for access.
---

4. If the user is a Manager with a level less than 20, output the message:

Output
---
You do not have sufficient privileges.
---

5. If the user is not an Admin or a Manager, output the message:

Output
---
You do not have sufficient privileges.
---

*/
string permission = "Admin|Manager";
int level = 53;


if (!permission.Contains("Admin") && !permission.Contains("Manager"))
{
  Console.WriteLine("You do not have sufficient privileges.");
} else if (permission.Contains("Admin"))
{
  string role = level > 55 ? "Super Admin" : "Admin";
  Console.WriteLine($"Welcome, {role}");
} else if (permission.Contains("Manager"))
{
  string msg = level > 20 ? "Contact an Admin for access." : "You do not have sufficient privileges.";
  Console.WriteLine(msg);
}

Exercise - Complete a challenge activity using for and if statements

/*

Output values from 1 to 100, one number per line, inside the code block of an iteration statement.
When the current value is divisible by 3, print the term Fizz next to the number.
When the current value is divisible by 5, print the term Buzz next to the number.
When the current value is divisible by both 3 and 5, print the term FizzBuzz next to the number.

*/

for (int i = 1; i < 101; i++)
{
  string retval = "";
  if (i % 3 == 0) retval += "Fizz";
  if (i % 5 == 0) retval += "Buzz";
  if (retval.Length > 0)
  {
    retval = $"{i} - " + retval;
  } else
  {
    retval = $"{i}";
  }
  Console.WriteLine(retval);
}

Exercise - Complete a challenge activity using do and while iteration statements

/*
You must use either the do-while statement or the while statement as an outer game loop.
The hero and the monster will start with 10 health points.
All attacks will be a value between 1 and 10.
The hero will attack first.
Print the amount of health the monster lost and their remaining health.
If the monster's health is greater than 0, it can attack the hero.
Print the amount of health the hero lost and their remaining health.
Continue this sequence of attacking until either the monster's health or hero's health is zero or less.
Print the winner.
*/

// The hero and the monster will start with 10 health points.
int heroHealth = 10;
int monsterHealth = 10;

Random hit = new Random();

// You must use either the do-while statement or the while statement as an outer game loop.
// If the monster's health is greater than 0, it can attack the hero.
do
{
  // The hero will attack first.
  // All attacks will be a value between 1 and 10.
  int monsterHitpoint = hit.Next(1, 10);
  monsterHealth -= monsterHitpoint;

  // Print the amount of health the monster lost and their remaining health.
  Console.WriteLine($"Monster was damaged and lost {monsterHitpoint} health and now has {monsterHealth} health.");
  if (monsterHealth <= 0) break;

  int heroHitpoint = hit.Next(1, 10);
  heroHealth -= heroHitpoint;

  // Print the amount of health the hero lost and their remaining health.
  Console.WriteLine($"Hero was damaged and lost {heroHitpoint} health and now has {heroHealth} health.");

  // Continue this sequence of attacking until either the monster's health or hero's health is zero or less.
  if (heroHealth <= 0) break;

} while (monsterHealth > 0);

string winner = heroHealth > monsterHealth ? "Hero" : "Monster";
Console.WriteLine($"{winner} wins!");

/* Example
Monster was damaged and lost 1 health and now has 9 health.
Hero was damaged and lost 1 health and now has 9 health.
Monster was damaged and lost 7 health and now has 2 health.
Hero was damaged and lost 6 health and now has 3 health.
Monster was damaged and lost 9 health and now has -7 health.
Hero wins!
*/

Exercise - Complete a challenge activity to differentiate between do and while iteration statements

Code project 1 - write code that validates integer input
/*

Your solution must include either a do-while or while iteration.

Before the iteration block: your solution must use a Console.WriteLine() statement to prompt the user for an integer value between 5 and 10.

Inside the iteration block:

Your solution must use a Console.ReadLine() statement to obtain input from the user.
Your solution must ensure that the input is a valid representation of an integer.
If the integer value isn't between 5 and 10, your code must use a Console.WriteLine() statement to prompt the user for an integer value between 5 and 10.
Your solution must ensure that the integer value is between 5 and 10 before exiting the iteration.
Below (after) the iteration code block: your solution must use a Console.WriteLine() statement to inform the user that their input value has been accepted.

*/
/* Output Example:
Enter an integer value between 5 and 10
two
Sorry, you entered an invalid number, please try again
2
You entered 2. Please enter a number between 5 and 10.
7
Your input value (7) has been accepted.
*/

// Before the iteration block:
// your solution must use a Console.WriteLine() statement to prompt the user for an integer value between 5 and 10.
Console.WriteLine("Enter an integer value between 5 and 10");

string? readResult;
bool validEntry = false;

// Your solution must include either a do-while or while iteration.
do
{
  // Your solution must use a Console.ReadLine() statement to obtain input from the user.
  readResult = Console.ReadLine();

  // Your solution must ensure that the input is a valid representation of an integer.
  int numericValue = 0;
  bool validNumber = false;

  validNumber = int.TryParse(readResult, out numericValue);
  if (!validNumber)
  {
    Console.WriteLine("Sorry, you entered an invalid number, please try again");
    continue;
  }
  if (validNumber)
  {
    if (numericValue > 11 || numericValue < 5)
    {
      Console.WriteLine($"You entered {numericValue}. Please enter a number between 5 and 10.");
      continue;
    }
    else
    {
      Console.WriteLine($"Your input value ({numericValue}) has been accepted.");
      validEntry = true;
    }
  }
} while (!validEntry);
Code project 2 - write code that validates string input
/*

Code project 2 - write code that validates string input

Your solution must include either a do-while or while iteration.

Before the iteration block: your solution must use a Console.WriteLine() statement to prompt the user for one of three role names: Administrator, Manager, or User.

Inside the iteration block:

Your solution must use a Console.ReadLine() statement to obtain input from the user.
Your solution must ensure that the value entered matches one of the three role options.
Your solution should use the Trim() method on the input value to ignore leading and trailing space characters.
Your solution should use the ToLower() method on the input value to ignore case.
If the value entered isn't a match for one of the role options, your code must use a Console.WriteLine() statement to prompt the user for a valid entry.
Below (after) the iteration code block: Your solution must use a Console.WriteLine() statement to inform the user that their input value has been accepted.
*/
/* Output Example:
Enter your role name (Administrator, Manager, or User)
Admin
The role name that you entered, "Admin" is not valid. Enter your role name (Administrator, Manager, or User)
   Administrator
Your input value (Administrator) has been accepted.

*/

// Before the iteration block: your solution must use a Console.WriteLine() statement
// to prompt the user for one of three role names: Administrator, Manager, or User.
Console.WriteLine("Enter your role name (Administrator, Manager, or User)");

string? readResult;
bool validEntry = false;

// Your solution must include either a do-while or while iteration.
do
{
  // Your solution must use a Console.ReadLine() statement to obtain input from the user.
  readResult = Console.ReadLine();
  string inputRole = readResult == null ? "" : readResult.Trim();
  // Your solution must ensure that the value entered matches one of the three role options.
  if (!inputRole.Contains("Administrator") && !inputRole.Contains("Manager") && !readResult.Contains("User"))
  {
    Console.WriteLine($"The role name that you entered, \"{inputRole}\" is not valid. Enter your role name (Administrator, Manager, or User)");
    continue;
  }
  else
  {
    Console.WriteLine($"Your input value ({inputRole}) has been accepted");
    validEntry = true;
  }
} while (!validEntry);
Code project 3 - Write code that processes the contents of a string array

/*

Code project 3 - Write code that processes the contents of a string array

your solution must use the following string array to represent the input to your coding logic:
---
string[] myStrings = new string[2] { "I like pizza. I like roast chicken. I like salad", "I like all three of the menu choices" };
---

Your solution must declare an integer variable named periodLocation that can be used to hold the location of the period character within a string.

Your solution must include an outer foreach or
for loop that can be used to process each string element in the array. The string variable that you'll process inside the loops should be named myString.

In the outer loop, your solution must use the IndexOf() method of the String class to get the location of the first period character in the myString variable. The method call should be similar to: myString.IndexOf("."). If there's no period character in the string, a value of -1 will be returned.

Your solution must include an inner do-while or while loop that can be used to process the myString variable.

In the inner loop, your solution must extract and display (write to the console) each sentence that is contained in each of the strings that are processed.

In the inner loop, your solution must not display the period character.

In the inner loop, your solution must use the Remove(), Substring(), and TrimStart() methods to process the string information.
*/
/* Output Example:
I like pizza
I like roast chicken
I like salad
I like all three of the menu choices

*/

// your solution must use the following string array to represent the input to your coding logic:
string[] myStrings = new string[2] { "I like pizza. I like roast chicken. I like salad", "I like all three of the menu choices" };

// Your solution must declare an integer variable named periodLocation that can be used to hold the location of the period character within a string.
int periodLocation = 0;

// Your solution must include an outer foreach or for loop that can be used to process each string element in the array. The string variable that you'll process inside the loops should be named myString.
foreach (string myString in myStrings)
{
  // In the outer loop, your solution must use the IndexOf() method of the String class to get the location of the first period character in the myString variable. The method call should be similar to: myString.IndexOf("."). If there's no period character in the string, a value of -1 will be returned.
  periodLocation = myString.IndexOf(".");
  // string sentence = myString.Substring(0, periodLocation);
  // Your solution must include an inner do-while or while loop that can be used to process the myString variable.
  string origin = myString;
  bool hasPeriod = true;
  string target = "";
  if (periodLocation == -1) {
    target = myString.Substring(0);
    Console.WriteLine(target.TrimStart());
    hasPeriod = false;
    break;
  } else {
    target = myString.Substring(0, periodLocation);
    Console.WriteLine(target.TrimStart());
  }
  origin = myString.Remove(0, target.Length + 1);
  periodLocation = origin.IndexOf(".");
  do
  {
    if (periodLocation == -1) {
      target = origin.Substring(0);
      Console.WriteLine(target.TrimStart());
      hasPeriod = false;
      break;
    } else{
      target = origin.Substring(0, periodLocation);
    }
    // In the inner loop, your solution must extract and display (write to the console) each sentence that is contained in each of the strings that are processed.
    // In the inner loop, your solution must not display the period character.
    Console.WriteLine(target.TrimStart());
    origin = origin.Remove(0, target.Length + 1);
    periodLocation = origin.IndexOf(".");
  } while (hasPeriod);
}

Exercise - Complete a challenge to combine string array values as strings and as integers
string[] values = { "12.3", "45", "ABC", "11", "DEF" };
bool isDecimal;
string resultMessag = "";
decimal resultValue = 0;
decimal outValue;

foreach (var value in values)
{
  isDecimal = decimal.TryParse(value, out outValue);
  if (isDecimal) resultValue += outValue;
  if (!isDecimal) resultMessag += value;
}
Console.WriteLine($"Message: {resultMessag}");
Console.WriteLine($"Total: {resultValue}");
Exercise - Complete a challenge to output math operations as specific number types
int value1 = 12;
decimal value2 = 6.2m;
float value3 = 4.3f;

// Your code here to set result1
// Hint: You need to round the result to nearest integer (don't just truncate)
int result1 = value1 / Convert.ToInt32(value2);
Console.WriteLine($"Divide value1 by value2, display the result as an int: {result1}");

// Your code here to set result2
decimal result2 = value2 / (decimal) value3;
Console.WriteLine($"Divide value2 by value3, display the result as a decimal: {result2}");

// Your code here to set result3
float result3 = value3 / value1;
Console.WriteLine($"Divide value3 by value1, display the result as a float: {result3}");
Exercise - Complete a challenge to reverse words in a sentence
/*
Write the code necessary to reverse the letters of each word in place and display the result.
In other words, don't just reverse every letter in the variable pangram. Instead, you'll need to reverse just the letters in each word, but print the reversed word in its original position in the message.

Expected result:
ehT kciuq nworb xof spmuj revo eht yzal god
*/
string pangram = "The quick brown fox jumps over the lazy dog";

// split string by space ({"The", "quick", .... })
string[] words = pangram.Split(" ");
string[] reverseWords = new string[words.Length];
for (int i = 0; i < words.Length; i++)
{
  char[] characters = words[i].ToCharArray();
  Array.Reverse(characters);
  reverseWords[i] = new string(characters);
}
Console.WriteLine(String.Join(" ", reverseWords));
Exercise - Complete a challenge to parse a string of orders, sort the orders and tag possible errors
// Notice in the previous code, the orderStream variable contains a string of multiple Order IDs separated by commas
// Order ID はカンマ区切りで複数。これを配列に格納する。
string orderStream = "B123,C234,A345,C15,B177,G3003,C235,B179";

/*
Add code below the previous code to parse the "Order IDs" from the string of incoming orders and store the "Order IDs" in an array
Add code to output each "Order ID" in sorted order and tag orders that aren't exactly four characters in length as "- Error"
*/
// Add code below the previous code to parse the "Order IDs" from the string of incoming orders and store the "Order IDs" in an array
string[] orderIds = orderStream.Split(",");
Array.Sort(orderIds);
foreach (string order in orderIds)
{
  if (order.Length != 4)
  {
    Console.WriteLine(order + "\t- Error");
  } else {
    Console.WriteLine(order);
  }
}
Add multiple term search support
using System;

// ourAnimals array will store the following:
string animalSpecies = "";
string animalID = "";
string animalAge = "";
string animalPhysicalDescription = "";
string animalPersonalityDescription = "";
string animalNickname = "";
string suggestedDonation = "";

// variables that support data entry
int maxPets = 8;
string? readResult;
string menuSelection = "";
decimal decimalDonation = 0.00m;

// array used to store runtime data
string[,] ourAnimals = new string[maxPets, 7];

// sample data ourAnimals array entries
for (int i = 0; i < maxPets; i++)
{
  switch (i)
  {
    case 0:
      animalSpecies = "dog";
      animalID = "d1";
      animalAge = "2";
      animalPhysicalDescription = "medium sized cream colored female golden retriever weighing about 45 pounds. housebroken.";
      animalPersonalityDescription = "loves to have her belly rubbed and likes to chase her tail. gives lots of kisses.";
      animalNickname = "lola";
      suggestedDonation = "85.00";
      break;

    case 1:
      animalSpecies = "dog";
      animalID = "d2";
      animalAge = "9";
      animalPhysicalDescription = "large reddish-brown male golden retriever weighing about 85 pounds. housebroken.";
      animalPersonalityDescription = "loves to have his ears rubbed when he greets you at the door, or at any time! loves to lean-in and give doggy hugs.";
      animalNickname = "gus";
      suggestedDonation = "49.99";
      break;

    case 2:
      animalSpecies = "cat";
      animalID = "c3";
      animalAge = "1";
      animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained.";
      animalPersonalityDescription = "friendly";
      animalNickname = "snow";
      suggestedDonation = "40.00";
      break;

    case 3:
      animalSpecies = "cat";
      animalID = "c4";
      animalAge = "";
      animalPhysicalDescription = "";
      animalPersonalityDescription = "";
      animalNickname = "lion";
      suggestedDonation = "";

      break;

    default:
      animalSpecies = "";
      animalID = "";
      animalAge = "";
      animalPhysicalDescription = "";
      animalPersonalityDescription = "";
      animalNickname = "";
      suggestedDonation = "";
      break;

  }

  ourAnimals[i, 0] = "ID #: " + animalID;
  ourAnimals[i, 1] = "Species: " + animalSpecies;
  ourAnimals[i, 2] = "Age: " + animalAge;
  ourAnimals[i, 3] = "Nickname: " + animalNickname;
  ourAnimals[i, 4] = "Physical description: " + animalPhysicalDescription;
  ourAnimals[i, 5] = "Personality: " + animalPersonalityDescription;

  if (!decimal.TryParse(suggestedDonation, out decimalDonation))
  {
    decimalDonation = 45.00m; // if suggestedDonation NOT a number, default to 45.00
  }
  ourAnimals[i, 6] = $"Suggested Donation: {decimalDonation:C2}";
}

// top-level menu options
do
{
  // NOTE: the Console.Clear method is throwing an exception in debug sessions
  Console.Clear();

  Console.WriteLine("Welcome to the Contoso PetFriends app. Your main menu options are:");
  Console.WriteLine(" 1. List all of our current pet information");
  Console.WriteLine(" 2. Display all dogs with a specified characteristic");
  Console.WriteLine();
  Console.WriteLine("Enter your selection number (or type Exit to exit the program)");

  readResult = Console.ReadLine();
  if (readResult != null)
  {
    menuSelection = readResult.ToLower();
  }

  // switch-case to process the selected menu option
  switch (menuSelection)
  {
    case "1":
      // list all pet info
      for (int i = 0; i < maxPets; i++)
      {
        if (ourAnimals[i, 0] != "ID #: ")
        {
          Console.WriteLine();
          for (int j = 0; j < 7; j++)
          {
            Console.WriteLine(ourAnimals[i, j].ToString());
          }
        }
      }

      Console.WriteLine("\r\nPress the Enter key to continue");
      readResult = Console.ReadLine();

      break;

    case "2":
      // #1 Display all dogs with a multiple search characteristics

      string dogCharacteristic = "";
      string[] dogCharacteristices = { };

      while (dogCharacteristic == "")
      {
        // #2 have user enter multiple comma separated characteristics to search for
        // Console.WriteLine($"\r\nEnter one desired dog characteristic to search for");
        Console.WriteLine($"\r\nEnter dog characteristics to search for separated by commas");
        readResult = Console.ReadLine();
        if (readResult != null)
        {
          dogCharacteristic = readResult.ToLower().Trim();
          dogCharacteristices = dogCharacteristic.Split(',');
          Array.Sort(dogCharacteristices);
          Console.WriteLine();
        }
      }

      bool noMatchesDog = true;
      string dogDescription = "";

      // #4 update to "rotating" animation with countdown
      string[] searchingIcons = { ".  ", ".. ", "..." };

      // loop ourAnimals array to search for matching animals
      for (int i = 0; i < maxPets; i++)
      {

        bool hasCharacteristics = false;
        for (int c = 0; c < dogCharacteristices.Length; c++)
        {
          dogCharacteristic = dogCharacteristices[c].Trim().Replace(" ", "");
          if (ourAnimals[i, 1].Contains("dog"))
          {

            // Search combined descriptions and report results
            dogDescription = ourAnimals[i, 4] + "\r\n" + ourAnimals[i, 5];

            for (int j = 5; j > -1; j--)
            {
              // #5 update "searching" message to show countdown
              /*foreach (string icon in searchingIcons)
              {
                Console.Write($"\rsearching our dog {ourAnimals[i, 3]} for {dogCharacteristic} {icon}");
                Thread.Sleep(250);
              }
              Console.Write($"\r{new String(' ', Console.BufferWidth)}");
              */
            }
            // #3a iterate submitted characteristic terms and search description for each term

            if (dogDescription.Contains(dogCharacteristic))
            {
              // #3b update message to reflect term
              // #3c set a flag "this dog" is a match
              /*
                  Our dog Nickname: lola matches your search for cream
                  Our dog Nickname: lola matches your search for golden
              */
              hasCharacteristics = true;
              Console.WriteLine($"Our dog {ourAnimals[i, 3]} matches your search for {dogCharacteristic}");

              noMatchesDog = false;
            }
            // #3d if "this dog" is match write match message + dog description
          }
        }
        if (hasCharacteristics)
        {
          {
            Console.WriteLine($"{ourAnimals[i, 3].ToString()} ({ourAnimals[i, 0].ToString()})");
            Console.WriteLine(ourAnimals[i, 4].ToString());
            Console.WriteLine(ourAnimals[i, 5].ToString());
            Console.WriteLine();
          }
        }
      }

      if (noMatchesDog)
      {
        Console.WriteLine("None of our dogs are a match for: " + readResult);
      }

      Console.WriteLine("\n\rPress the Enter key to continue");
      readResult = Console.ReadLine();

      break;

    default:
      break;
  }

} while (menuSelection != "exit");
Exercise - Add improved search animation
using System;

// ourAnimals array will store the following:
string animalSpecies = "";
string animalID = "";
string animalAge = "";
string animalPhysicalDescription = "";
string animalPersonalityDescription = "";
string animalNickname = "";
string suggestedDonation = "";

// variables that support data entry
int maxPets = 8;
string? readResult;
string menuSelection = "";
decimal decimalDonation = 0.00m;

// array used to store runtime data
string[,] ourAnimals = new string[maxPets, 7];

// sample data ourAnimals array entries
for (int i = 0; i < maxPets; i++)
{
  switch (i)
  {
    case 0:
      animalSpecies = "dog";
      animalID = "d1";
      animalAge = "2";
      animalPhysicalDescription = "medium sized cream colored female golden retriever weighing about 45 pounds. housebroken.";
      animalPersonalityDescription = "loves to have her belly rubbed and likes to chase her tail. gives lots of kisses.";
      animalNickname = "lola";
      suggestedDonation = "85.00";
      break;

    case 1:
      animalSpecies = "dog";
      animalID = "d2";
      animalAge = "9";
      animalPhysicalDescription = "large reddish-brown male golden retriever weighing about 85 pounds. housebroken.";
      animalPersonalityDescription = "loves to have his ears rubbed when he greets you at the door, or at any time! loves to lean-in and give doggy hugs.";
      animalNickname = "gus";
      suggestedDonation = "49.99";
      break;

    case 2:
      animalSpecies = "cat";
      animalID = "c3";
      animalAge = "1";
      animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained.";
      animalPersonalityDescription = "friendly";
      animalNickname = "snow";
      suggestedDonation = "40.00";
      break;

    case 3:
      animalSpecies = "cat";
      animalID = "c4";
      animalAge = "";
      animalPhysicalDescription = "";
      animalPersonalityDescription = "";
      animalNickname = "lion";
      suggestedDonation = "";

      break;

    default:
      animalSpecies = "";
      animalID = "";
      animalAge = "";
      animalPhysicalDescription = "";
      animalPersonalityDescription = "";
      animalNickname = "";
      suggestedDonation = "";
      break;

  }

  ourAnimals[i, 0] = "ID #: " + animalID;
  ourAnimals[i, 1] = "Species: " + animalSpecies;
  ourAnimals[i, 2] = "Age: " + animalAge;
  ourAnimals[i, 3] = "Nickname: " + animalNickname;
  ourAnimals[i, 4] = "Physical description: " + animalPhysicalDescription;
  ourAnimals[i, 5] = "Personality: " + animalPersonalityDescription;

  if (!decimal.TryParse(suggestedDonation, out decimalDonation))
  {
    decimalDonation = 45.00m; // if suggestedDonation NOT a number, default to 45.00
  }
  ourAnimals[i, 6] = $"Suggested Donation: {decimalDonation:C2}";
}

// top-level menu options
do
{
  // NOTE: the Console.Clear method is throwing an exception in debug sessions
  Console.Clear();

  Console.WriteLine("Welcome to the Contoso PetFriends app. Your main menu options are:");
  Console.WriteLine(" 1. List all of our current pet information");
  Console.WriteLine(" 2. Display all dogs with a specified characteristic");
  Console.WriteLine();
  Console.WriteLine("Enter your selection number (or type Exit to exit the program)");

  readResult = Console.ReadLine();
  if (readResult != null)
  {
    menuSelection = readResult.ToLower();
  }

  // switch-case to process the selected menu option
  switch (menuSelection)
  {
    case "1":
      // list all pet info
      for (int i = 0; i < maxPets; i++)
      {
        if (ourAnimals[i, 0] != "ID #: ")
        {
          Console.WriteLine();
          for (int j = 0; j < 7; j++)
          {
            Console.WriteLine(ourAnimals[i, j].ToString());
          }
        }
      }

      Console.WriteLine("\r\nPress the Enter key to continue");
      readResult = Console.ReadLine();

      break;

    case "2":
      // #1 Display all dogs with a multiple search characteristics

      string dogCharacteristic = "";
      string[] dogCharacteristices = { };

      while (dogCharacteristic == "")
      {
        // #2 have user enter multiple comma separated characteristics to search for
        // Console.WriteLine($"\r\nEnter one desired dog characteristic to search for");
        Console.WriteLine($"\r\nEnter dog characteristics to search for separated by commas");
        readResult = Console.ReadLine();
        if (readResult != null)
        {
          dogCharacteristic = readResult.ToLower().Trim();
          dogCharacteristices = dogCharacteristic.Split(',');
          Array.Sort(dogCharacteristices);
          Console.WriteLine();
        }
      }

      bool noMatchesDog = true;
      string dogDescription = "";

      // #4 update to "rotating" animation with countdown
      string[] searchingIcons = { " |", " /", "--", " \\", " *" };

      // loop ourAnimals array to search for matching animals
      for (int i = 0; i < maxPets; i++)
      {

        bool hasCharacteristics = false;
        for (int c = 0; c < dogCharacteristices.Length; c++)
        {
          dogCharacteristic = dogCharacteristices[c].Trim().Replace(" ", "");
          if (ourAnimals[i, 1].Contains("dog"))
          {

            // Search combined descriptions and report results
            dogDescription = ourAnimals[i, 4] + "\r\n" + ourAnimals[i, 5];

            for (int j = 2; j > -1; j--)
            {
              // #5 update "searching" message to show countdown
              for (int k = 0; k < searchingIcons.Length; k++)
              {
                string icon = searchingIcons[k];
                Console.Write($"\rsearching our dog {ourAnimals[i, 3]} for {dogCharacteristic} {icon} {j}");
                Thread.Sleep(100);
              }
              Console.Write($"\r{new String(' ', Console.BufferWidth)}");
            }
            // #3a iterate submitted characteristic terms and search description for each term

            if (dogDescription.Contains(" " + dogCharacteristic.Trim() + " "))
            {
              // #3b update message to reflect term
              // #3c set a flag "this dog" is a match
              /*
                  Our dog Nickname: lola matches your search for cream
                  Our dog Nickname: lola matches your search for golden
              */
              hasCharacteristics = true;
              // Console.WriteLine($"Our dog {ourAnimals[i, 3]} matches your search for {dogCharacteristic}");
              Console.WriteLine($"\rOur dog {ourAnimals[i, 3]} matches your search for {dogCharacteristic.Trim()}");
              noMatchesDog = false;
            }
            // #3d if "this dog" is match write match message + dog description
          }
        }
        if (hasCharacteristics)
        {
          {
            Console.WriteLine($"{ourAnimals[i, 3].ToString()} ({ourAnimals[i, 0].ToString()})");
            Console.WriteLine(ourAnimals[i, 4].ToString());
            Console.WriteLine(ourAnimals[i, 5].ToString());
            Console.WriteLine();
          }
        }
      }

      if (noMatchesDog)
      {
        Console.WriteLine("None of our dogs are a match for: " + readResult);
      }

      Console.WriteLine("\n\rPress the Enter key to continue");
      readResult = Console.ReadLine();

      break;

    default:
      break;
  }

} while (menuSelection != "exit");

Discussion