Adan
Adan

Reputation: 65

C# How to work-around identical keys in a Dictionary

This program add's values with their other values into a dictionary, all is fine until there are identical keys (var eat(.8) and var extra(.8) with different values. How do i ensure that i can use the right key every time even though they are similar? For example, var example = gigantDictionary[.8] (but i want var edmg value instead of '500' in the code?

var wqat = 1.1;  //| index 0
var rat = .2;    //| index 1
var eat = .8;    //| index 2
var baat = 1.2;  //| index 3
var extra = .8;  //| index 4


var wqdmg = 120; //| index 0
var rdmg = 60;   //| index 1
var edmg = 50;   //| index 2
var badmg = 40;  //| index 3
var extradmg = 500; //| index 4



List<double> theOneList = new List<double>();
List<double> damageList = new List<double>();

theOneList.Add(wqat);
theOneList.Add(rat);
theOneList.Add(eat);
theOneList.Add(baat);


damageList.Add(wqdmg);
damageList.Add(edmg);
damageList.Add(rdmg);
damageList.Add(badmg);

Dictionary<double, double> gigantDictionary = new Dictionary<double, double>();



for (int i = 0; i < theOneList.Count; i++)
{
    gigantDictionary.Add(theOneList[i], damageList[i]);
    gigantDictionary.Add(extra, 500); //this is the malignant similar key


}

 theOneList.Sort((c, p) => -c.CompareTo(p)); //orders the list

List<double> finalList = new List<double>(); 

 for (int i = 0; i < theOneList.Count; i++)
        {
            finalList.Add(gigantDictionary[theOneList[i]]); //grabs damage values and add's it to 'finalList'

           Console.WriteLine(finalList[i]);
        }

So ultimately, i want to order 'theOneList' by descent, in doing so i can get the damages from 'gigantDictionary' and put those into 'finalList', now i have an ordered damage list that i need, but since 2 keys are similar... this is holding me back.

*Edit: Could identical indexes be the key to this? be the bridge? for example, in index 0 i get 1.1 and 120, maybe the answer lies with the identical indexes, i want to get '120' damage from '1.1', notice both have index 0, this might work

Upvotes: 0

Views: 84

Answers (2)

John Alexiou
John Alexiou

Reputation: 29274

Right now you have two separate list for values that must go together. A better approach is to create a structure with the two values and keep a single list.

public class Thing
{
    public string Name { get; set; }
    public double TheOne { get; set; }
    public double Dmg { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<Thing> list=new List<Thing>() {
            new Thing() { Name = "wq", TheOne = 1.1, Dmg=120 },
            new Thing() { Name = "r", TheOne = 0.2, Dmg=60 },
            new Thing() { Name = "e", TheOne = 0.8, Dmg=50 },
            new Thing() { Name = "ba", TheOne = 1.2, Dmg=40 },
            new Thing() { Name = "extra", TheOne = 0.8, Dmg=500 },
        };

        list.Sort((t1, t2) => t1.TheOne.CompareTo(t2.TheOne));

        double[] dmg_list=list.Select((t) => t.Dmg).ToArray();

    }
}

Edit 1

A constructor to Thing can be used to assign values with one operation.

public class Thing
{
    // Constructor sets all the values
    public Thing(string name, double theone, double dmg)
    {
        this.Name=name;
        this.TheOne=theone;
        this.Dmg=dmg;
    }
    public string Name { get; private set; }
    public double TheOne { get; private set; }
    public double Dmg { get; private set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<Thing> list=new List<Thing>();
        list.Add(new Thing("wq", 1.1, 120));
        list.Add(new Thing("r", 0.2, 60));
        list.Add(new Thing("e", 0.8, 50));
        list.Add(new Thing("ba", 1.2, 40));
        list.Add(new Thing("extra", 0.8, 500));


        list.Sort((t1, t2) => t1.TheOne.CompareTo(t2.TheOne));

        double[] dmg_list=list.Select((t) => t.Dmg).ToArray();

    }
}

Upvotes: 1

Servy
Servy

Reputation: 203847

They keys aren't "similar" they're "identical". If the keys were just "similar" then, as far as the dictionary is concerned, it's no different than being "completely different". From the point of view of a dictionary items are either equal, or not equal.

For example,

var example = gigantDictionary[.8] 

(but i want var edmg value instead of '500' in the code?)

But how should the dictionary possibly know that? How would it know if you actually wanted to get 500?

Do you want to prevent the duplicate keys from being added, and instead always use the first value paired with every key? If so, just check if a key exists before adding a new one.

Do you want to just get all values associated with a key, if there are duplicates? Then have a dictionary where the value is a collection, and add all values associated with that one key to the collection.

Is there actually some way to distinguish the keys so that they're not actually identical? Then do that. With just a double (which is a very bad type to use as a key for a dictionary in the first place, as it's easy for floating point rounding errors to result in similar but different doubles that you consider equivalent) there's no good way to do this, but if your actual key could be different in such a way that distinguishes the two keys, then each could point to a unique value.

Upvotes: 2

Related Questions