0

I am trying to find a way to detect if there is/are the same text in array input, all five of the Name input must be different, and if there is any similarity, it will automatically request input again.

Example:

Name 1: Max
Address 1: address a

Name 2: Max
Address 2: address b

You can see that both of the name input is similar, i want it to Console.WriteLine("The name is already added, please add a different name); and request input for Name 2 again.

Just like this:

Name 1: Max
Address 1: address a

Name 2: Max
Address 2: address b

Name is already added, Please input a different name!`
Name 2: Minimum

Here is my code so far:

    var a = 5;
    string[,] input = new string[a, 2];

    for (a = 0; a < 5; a++)
    {
        Console.Write($"Name {a + 1} : ");
        input[a, 0] = Console.ReadLine();
        input[a, 0] = input[a, 0].ToLower();
        Console.Write($"Address {a + 1} : ");
        input[a, 1] = Console.ReadLine();
        
    }

NOTE: This is between five inputs

2

2 Answers 2

1

You can use HashSet<string> to store unique strings (names):

  //DONE: it's unclear what "a" name means, let it be "count"
  var count = 5;
  //TODO: I've kept 2d array from the question, 
  // a class (tuple) will be better here 
  string[,] input = new string[count, 2];
  
  var takenNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

  //DONE: don't use magic constants - 5
  for (int i = 0; i < input.GetLength(0); ++i) {
    // Keep asking user until unique name is provided:
    while (true) {
      Console.Write($"Name {i + 1} : ");
      input[i, 0] = Console.ReadLine();

      // stop asking if and only if the name is unique  
      if (takenNames.Add(input[i, 0]))
        break;

      Console.WriteLine("Name is already added, Please input a different name!");
    }   

    Console.Write($"Address {i + 1} : ");
    input[i, 1] = Console.ReadLine();       
  }

Edit: As Dai mentioned in the comments, an array of custom classes, named tuples, records etc. is better design then 2d array of strings, e.g.

  var count = 5;
  // let it be readable: named tuple with name and address properties  
  var input = new (string name, string address)[count];

  var takenNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

  for (int i = 0; i < input.GetLength(0); ++i) {
    // Keep asking user until unique name is provided:
    while (true) {
      Console.Write($"Name {i + 1} : ");
      input[i].name = Console.ReadLine();

      // stop asking if and only if the name is unique  
      if (takenNames.Add(input[i].name))
        break;

      Console.WriteLine("Name is already added, Please input a different name!");
    }

    Console.Write($"Address {i + 1} : ");
    input[i].address = Console.ReadLine();
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Good stuff - though that string[,] (from the OP's code, I know) with const/literal indexes makes me wince - can you change it to use a ValueTuple with named members instead?
@Dai: I vote for a custom class and, probably, with overriden Equals and GetHashCode for easier duplicate check. I totally agree with you that string[,] is (very) bad design here, but changing to named tuples can well ruin business logic which manipulates with string[,], that's why I stuck to string[,]. I've edited the answer and provide a version with named tuple.
0

Here is a basic example. You can cut and paste into Linqpad to try it

EDIT Corrected to take into account @Dai comment about the Dictionary constructor overload that takes an IEqualityComparer instance as argument. See the doc about this constructor, and the doc about the StringComparer.

void Main()
{
    var personCount = 5;
    var persons = new Dictionary<string, Person>(StringComparer.OrdinalIgnoreCase);
    
    for (int i = 0; i < personCount; i++)
    {
        var newPerson = new Person();
        Console.WriteLine("Enter a name");
        var name = Console.ReadLine();
        while(persons.ContainsKey(name))
        {
            Console.WriteLine("This name already exists, please enter a new name");
            name = Console.ReadLine();
        }
        newPerson.Name = name;
        Console.WriteLine("Enter an address");
        newPerson.Address = Console.ReadLine();
        persons.Add(name, newPerson);
    }
}

// You can define other methods, fields, classes and namespaces here

public class Person
{
    public string Name { get; set; }
    public string Address { get; set; }
}

3 Comments

Please don't use PascalCase for locals. We aren't writing VB6 here.
Persons.Add(Name.ToLower(), NewPerson); <-- This is incorrect. Don't use .ToLower() for the sake of case-insensitive string keys in a dictionary. Instead pass StringComparer.OrdinalIgnoreCase into the Dictionary constructor.
Thanks! I should have looked in the Dictionary overloads. I'll remember this. I'll correct my post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.