Home > database >  Prevent duplicate variables of the objects added as Values in a dictionary c#
Prevent duplicate variables of the objects added as Values in a dictionary c#

Time:11-06

I have a Dictionary<int,int> in my Individual class.

 public class Individual
    {
       Dictionary<int,int> pattern = new Dictionary<int,int>();
    }

I want to add an <int,Individual> pair to my population dictionary:

Dictionary<int,Individual> population = new Dictionary<int, Individual>();

If and only if there is no other Individual in the dictionary with a similar pattern variable.

My current approach is to naively iterate over every pattern of every Individual already present in the population, but I believe this can be done faster using a different approach.

public bool same_dict(Dictionary<int, int> p1, Dictionary<int, int> p2)
//Meant to compare patterns
{
    if (p1.Count != p1.Count) return false;
    foreach (var feature in p1)
    {
        if (p2.ContainsKey(feature.Key))
        {
            if (feature.Value != p2[feature.Key]) return false;
        }
        else return false;
    }
    return true;
}

public bool matched is_duplicated(Individual ind, Dictionary<int, Individual> pop)
{
//Meant to compare Individuals
    foreach (var ind2 in pop)
    {
        if (same_dict(ind.pattern, ind2.Value.pattern))
        {
            return true;
        }
    }
    return false;
} 

I must use the ints as keys for the population dictionary because I use it to link the Individual objects with other parts of the program. A pattern dictionary can contain any amount of key:value pairs, that's why I verify if their .Count property is the same.

CodePudding user response:

I'm not sure that i correctly understand your issue, but...

If and only if there is no other Individual in the dictionary with a similar pattern variable

"Similar pattern variable" means, as I think, that two Individual has Pattern dictionary with same key(s) and value(s) in it (don't know, how much "patterns" it could store).

So I tried to use LINQ's .Any() extension method to check for any Individual's Pattern dictionary in population dictionary has same key and value as added Individual. It sounds complicated, so here is code example (console):

public class Individual
{
    public Dictionary<int, int> Pattern { get; set; } = new Dictionary<int, int>();
}

static void Main()
{
    var population = new Dictionary<int, Individual>();
    var key = 0;

    for (; key < 5; key  ) // Fill population with some Individuals
    {
        var individual = new Individual();
        individual.Pattern.Add(key   1, key   2);

        population.Add(key, individual);
    }

    // Print current population:
    Console.WriteLine("Population Dictionary:");
    foreach (var kvp in population)
        Console.WriteLine(kvp.Key   ": "  
                          string.Join(" | ", kvp.Value.Pattern.Select(pattern => pattern.Key   ","   pattern.Value)));

    // Creating new Individuals, which we will try to add to population
    var newIndividual1 = new Individual();
    newIndividual1.Pattern.Add(5, 6);
    var newIndividual2 = new Individual();
    newIndividual2.Pattern.Add(5, 5);
    var newIndividual3 = new Individual();
    newIndividual3.Pattern.Add(8, 9);

    Console.WriteLine();
    Console.WriteLine("Adding new Individuals:");

    if (AddIndividual(population, key, newIndividual1))
        key  ;

    if (AddIndividual(population, key, newIndividual2))
        key  ;

    if (AddIndividual(population, key, newIndividual3))
        key  ;

    Console.ReadKey();
}

static bool AddIndividual(Dictionary<int, Individual> population, int newKey, Individual newIndividual)
{
    // Compare each Individual in population with newIndividual
    if (!population.Any(p => newIndividual.Pattern.Keys.Any(k => p.Value.Pattern.ContainsKey(k)) &&
                             newIndividual.Pattern.Values.Any(v => p.Value.Pattern.ContainsValue(v))))
    {
        population.Add(newKey, newIndividual);
        Console.WriteLine("Individual with pattern "  
                          string.Join(" | ", newIndividual.Pattern.Select(pattern => pattern.Key   ","   pattern.Value))  
                          " successfully added to Population Dictionary.");

        return true;
    }
    else
    {
        Console.WriteLine("Individual with pattern "  
                          string.Join(" | ", newIndividual.Pattern.Select(pattern => pattern.Key   ","   pattern.Value))  
                          " already exists in Population Dictionary.");

        return false;
    }
}

Output sample:

enter image description here

EDIT.

You can replace comparing keys and values by .Any method with .SequenceEqual:

if (!population.Any(p => p.Value.Pattern.OrderBy(kvp => kvp.Key).SequenceEqual(newIndividual.Pattern.OrderBy(kvp => kvp.Key))))
{
    population.Add(newKey, newIndividual);
}
  • Related