kalka79
kalka79

Reputation: 31

c# nested loops- get distinct elements from List (without Linq)

If I have a List which contains some possibly duplicated string elements e.g. "dog","cat","dog","cow","cow","owl". I need to get the distinct elements from that list ( so I need to write the list of all elements without repetitive ones i.e. "dog","cat","cow","owl"). There must be a way how to use it with nested loops but I got stuck on something below:

IList<string> animals;
int a = animals.Count();
for (int i=0; i<a; i++)
   {
    foreach (string animal in animals)
    {
     if (animals[i+1] != animals[i])
      {
       Console.WriteLine(animals[i]);
       }
    }
  }

This is something close but it's not the correct one. Perhaps the nested inner loop should be "while" or another "for". Appreciate any tip on above. Thanks!

Upvotes: 0

Views: 1388

Answers (5)

Steve
Steve

Reputation: 216343

Use an HashSet<string> This class is similar to a List but doesn't allow duplicates

IList<string> animals = new List<string> {"Lion", "Wolf", "Tiger", "Dog", "Cat", "Lion", "Tiger"};
HashSet<string> uniques = new HashSet<string>(animals);
foreach(animal in uniques)
   Console.WriteLIne(animal);

If you want to use a loop you could simplify your code using a second list where you will store unique values and while at it you can also avoid false uniqueness when the only difference is case upper or lower in the animal name

IList<string> animals = new List<string> {"Lion", "Wolf", "Tiger", "Dog", "Cat", "Lion", "tiger"};
List<string> uniques = new List<string>();
foreach (string animal in animals)
{
    if (!SearchCaseInsensitive(uniques, animal))
        uniques.Add(animal);
}
foreach(string animal in uniques)
    Console.WriteLine(animal);


bool SearchCaseInsensitive(List<string> source, string search)
{
    string lowerCaseSearch = search.ToLower();
    foreach(string animal in source)
        if(animal.ToLower() == lowerCaseSearch)
            return true;
    return false;
}

Upvotes: 1

Anu Viswan
Anu Viswan

Reputation: 18163

One way to achieve this would to use a loop to iterate the elements and add to another collection, each time you encounter a new one. For example,

var unique = new List<string>();
foreach(var animal in animals)
{
    if(!unique.Contains(animal))
    {
        unique.Add(animal);
    }
}

foreach(var item in unique)
{
    Console.WriteLine(item);
}

If you collection contains too many elements, a Dictionary with a faster look up might be a better solution than List. For example

var unique = new Dictionary<string,int>();
foreach(var animal in animals)
{
    if(!unique.ContainsKey(animal))
    {
        unique.Add(animal,1);
    }
}

foreach(var item in unique)
{
    Console.WriteLine(item.Key);
}

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186823

Yet another HashSet<string> solution:

HashSet<string> unique = new HashSet<string>();

foreach(var animal in animals)
  if (unique.Add(animal))
    Console.WriteLine(animal);

Upvotes: 0

Mashood Murtaza
Mashood Murtaza

Reputation: 497

List<string> animals new List<string> {"dog","cat","dog","cow","cow","owl"};  // your animals list

List<string> sorted = new List<string>();
foreach(string animal in animals)
{
     if (!sorted.Contains(animal))
      {
        sorted.Add(animal);
      }
}

Upvotes: 0

David Khachatryan
David Khachatryan

Reputation: 41

I'll recommend using HashSet.

HashSet<string> uniqueAnimals = new HashSet<string>(animals);

Upvotes: 0

Related Questions