I'm working on a add-in where I have to store a bunch of coordinates. I'm still a bit new to the api but would using a Dictionary to store the values be the best and most efficient way? I'm not sure what the Tvalue should be? Sorry for the beginner question. Thank you.
IDictionary<XYZ, Tvalue> myDictionary = new Dictionary<XYZ, Tvalue>();
myDictionary.Add(new XYZ(1.256, 1.885, 2.5685), 1);
Solved! Go to Solution.
I'm working on a add-in where I have to store a bunch of coordinates. I'm still a bit new to the api but would using a Dictionary to store the values be the best and most efficient way? I'm not sure what the Tvalue should be? Sorry for the beginner question. Thank you.
IDictionary<XYZ, Tvalue> myDictionary = new Dictionary<XYZ, Tvalue>();
myDictionary.Add(new XYZ(1.256, 1.885, 2.5685), 1);
Solved! Go to Solution.
Solved by DavidWoodCT. Go to Solution.
Hi!
You should create your own IEqualityComparer<XYZ> and pass its instance to Dictionary constructor.
But be very careful in comparing XYZ and/or doubles. Do not forget about tolerance and how doubles are stored in computer memory.
So, I think, you shouldn't define some logic in IEqualityComparer.GetHashCode() method, but just return constant. Rounding coordinates is dangerous in such cases. For example you round with 0.01 tolerance. First point X coordinate is 0.055000001, second point X coordinate is 0.054999999, they are very close, but Math.Round(0.055000001, 2) equals to 0.06 and Math.Round(0.054999999, 2) equals to 0.05.
Technically in such case we actually loose advantages of quick search in dictionary, but save the advantage of useful dictionary interface
Hi!
You should create your own IEqualityComparer<XYZ> and pass its instance to Dictionary constructor.
But be very careful in comparing XYZ and/or doubles. Do not forget about tolerance and how doubles are stored in computer memory.
So, I think, you shouldn't define some logic in IEqualityComparer.GetHashCode() method, but just return constant. Rounding coordinates is dangerous in such cases. For example you round with 0.01 tolerance. First point X coordinate is 0.055000001, second point X coordinate is 0.054999999, they are very close, but Math.Round(0.055000001, 2) equals to 0.06 and Math.Round(0.054999999, 2) equals to 0.05.
Technically in such case we actually loose advantages of quick search in dictionary, but save the advantage of useful dictionary interface
The Building Coder provides several examples of implementing equality comparers for Revit API XYZ coordinates.
The Building Coder provides several examples of implementing equality comparers for Revit API XYZ coordinates.
Hi dkam47!
If you just need to Store some XYZ values, wouldn't you be better using a List<XYZ> rather than a Dictionary?
Dictionaries are good when you want to 'look up' a value using a key (you can use the Key to retrieve the corresponding Value).
So, using a contrived example I've just made up, you could use a Dictionary<ElementId, XYZ> to store the ElementIds and corresponding LocationPoints of a series of elements, and then when you need to get an element's XYZ, you just look it up using the ElementId.
That's just a silly example to explain how dictionaries work: When I started coding, I took me a while to 'get' what a dictionary was useful for. YMMV!
HTH!
Hi dkam47!
If you just need to Store some XYZ values, wouldn't you be better using a List<XYZ> rather than a Dictionary?
Dictionaries are good when you want to 'look up' a value using a key (you can use the Key to retrieve the corresponding Value).
So, using a contrived example I've just made up, you could use a Dictionary<ElementId, XYZ> to store the ElementIds and corresponding LocationPoints of a series of elements, and then when you need to get an element's XYZ, you just look it up using the ElementId.
That's just a silly example to explain how dictionaries work: When I started coding, I took me a while to 'get' what a dictionary was useful for. YMMV!
HTH!
Also bear in mind that if you add a duplicate key with the same XYZ info for the key, C# is going to complain. As others have suggested, a List might be better than a Dictionary, as you don't need to worry about duplicates.
Also bear in mind that if you add a duplicate key with the same XYZ info for the key, C# is going to complain. As others have suggested, a List might be better than a Dictionary, as you don't need to worry about duplicates.
Thank you dwood and Dave. I will need to look up and retrieve the values so that is why I thought a Dictionary or ArrayList would be the better options. Thank you!
Thank you dwood and Dave. I will need to look up and retrieve the values so that is why I thought a Dictionary or ArrayList would be the better options. Thank you!
Sorry. It's Monday morning and I just got off a long flight but what I actually need to do is assign static coordinate XYZ values to a view. So for instance I want view 'A' to be located at predetermined XYZ location and view 'B' to be assigned to another predetermined XYZ location.
I thought it would be as easy as creating a new Dictionary with key and values for XYZ. I'm still fairly new to the api so it will be a learning experience. Thanks for the help!
Sorry. It's Monday morning and I just got off a long flight but what I actually need to do is assign static coordinate XYZ values to a view. So for instance I want view 'A' to be located at predetermined XYZ location and view 'B' to be assigned to another predetermined XYZ location.
I thought it would be as easy as creating a new Dictionary with key and values for XYZ. I'm still fairly new to the api so it will be a learning experience. Thanks for the help!
Here's what I got to work. There may be a better or efficient way to do this but here's where I landed. Thanks for the help.
IDictionary<double, XYZ> myDictionary = new Dictionary<double, XYZ>();
XYZ CorOne = new XYZ(2.3, 6.7, 8.0);
XYZ CorTwo = new XYZ(7.9, 4.7, 8.3);
myDictionary.Add(1, CorOne);
TaskDialog.Show("Debug Coordinate", myDictionary[1].ToString());
Here's what I got to work. There may be a better or efficient way to do this but here's where I landed. Thanks for the help.
IDictionary<double, XYZ> myDictionary = new Dictionary<double, XYZ>();
XYZ CorOne = new XYZ(2.3, 6.7, 8.0);
XYZ CorTwo = new XYZ(7.9, 4.7, 8.3);
myDictionary.Add(1, CorOne);
TaskDialog.Show("Debug Coordinate", myDictionary[1].ToString());
Dear Dkam47,
That looks utterly dangerous to me.
If you need a dictionary, you need to look up values based on the dictionary keys.
In this case, you are using double objects as keys.
The default comparison operator provided for those by .NET will probably not do what you expect.
If you really need dictionary and key lookup, you really have to implement your own non-default double key comparison operator making use of a fuzzy comparison:
If you do not need dictionaries and double lookup keys, do not use them!
What do those double values represent?
Are you using them as lookup keys?
Read about the different purposes yourself.
There is heaps of documentation out there, e.g., searching for '.net list dictionary'
https://duckduckgo.com/?q=.net+list+dictionary
Best regards,
Jeremy
Dear Dkam47,
That looks utterly dangerous to me.
If you need a dictionary, you need to look up values based on the dictionary keys.
In this case, you are using double objects as keys.
The default comparison operator provided for those by .NET will probably not do what you expect.
If you really need dictionary and key lookup, you really have to implement your own non-default double key comparison operator making use of a fuzzy comparison:
If you do not need dictionaries and double lookup keys, do not use them!
What do those double values represent?
Are you using them as lookup keys?
Read about the different purposes yourself.
There is heaps of documentation out there, e.g., searching for '.net list dictionary'
https://duckduckgo.com/?q=.net+list+dictionary
Best regards,
Jeremy
I agree with Jeremy (of course! :))
On the face of your code, you are not doing anything that cannot be done with a generic List<T>. Something like this maybe:
var myList = new List<XYZ>();
var CorOne = new XYZ(2.3, 6.7, 8.0);
var CorTwo = new XYZ(7.9, 4.7, 8.3);
myList.Add(CorOne);
myList.Add(CorTwo);
TaskDialog.Show("Debug Coordinate", myList[1].ToString());
TaskDialog.Show("Debug Coordinate", myList[2].ToString());
I agree with Jeremy (of course! :))
On the face of your code, you are not doing anything that cannot be done with a generic List<T>. Something like this maybe:
var myList = new List<XYZ>();
var CorOne = new XYZ(2.3, 6.7, 8.0);
var CorTwo = new XYZ(7.9, 4.7, 8.3);
myList.Add(CorOne);
myList.Add(CorTwo);
TaskDialog.Show("Debug Coordinate", myList[1].ToString());
TaskDialog.Show("Debug Coordinate", myList[2].ToString());
Can't find what you're looking for? Ask the community or share your knowledge.