Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dictionary<XYZ>

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
dkam47
1720 Views, 10 Replies

Dictionary<XYZ>

dkam47
Enthusiast
Enthusiast

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);

 

 

0 Likes

Dictionary<XYZ>

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);

 

 

10 REPLIES 10
Message 2 of 11
aignatovich
in reply to: dkam47

aignatovich
Advisor
Advisor

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

 

0 Likes

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

 

Message 3 of 11
jeremytammik
in reply to: dkam47

jeremytammik
Autodesk
Autodesk

The Building Coder provides several examples of implementing equality comparers for Revit API XYZ coordinates.



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

The Building Coder provides several examples of implementing equality comparers for Revit API XYZ coordinates.



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 11
dkam47
in reply to: dkam47

dkam47
Enthusiast
Enthusiast
Thank you aignatovich and Jeremy for pointing me in the right direction. I'm unfamiliar with the equality compares but have looked over the examples. I'll have to dig into it some more.
0 Likes

Thank you aignatovich and Jeremy for pointing me in the right direction. I'm unfamiliar with the equality compares but have looked over the examples. I'll have to dig into it some more.
Message 5 of 11
DavidWoodCT
in reply to: dkam47

DavidWoodCT
Enthusiast
Enthusiast
Accepted solution

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!

Message 6 of 11
Anonymous
in reply to: dkam47

Anonymous
Not applicable

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.

0 Likes

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.

Message 7 of 11
dkam47
in reply to: Anonymous

dkam47
Enthusiast
Enthusiast

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!

 
 
Message 8 of 11
dkam47
in reply to: dkam47

dkam47
Enthusiast
Enthusiast

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!

0 Likes

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!

Message 9 of 11
dkam47
in reply to: DavidWoodCT

dkam47
Enthusiast
Enthusiast

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.36.78.0);

            XYZ CorTwo = new XYZ(7.9, 4.78.3);
            
            myDictionary.Add(1, CorOne);
            
            TaskDialog.Show("Debug Coordinate", myDictionary[1].ToString());

 

 

0 Likes

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.36.78.0);

            XYZ CorTwo = new XYZ(7.9, 4.78.3);
            
            myDictionary.Add(1, CorOne);
            
            TaskDialog.Show("Debug Coordinate", myDictionary[1].ToString());

 

 

Message 10 of 11
jeremytammik
in reply to: dkam47

jeremytammik
Autodesk
Autodesk

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:

 

http://thebuildingcoder.typepad.com/blog/2017/06/sensors-bim-ai-revitlookup-and-fuzzy-comparison.htm...

 

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

 

https://stackoverflow.com/questions/7914830/what-is-the-difference-between-list-and-dictionary-in-c-...

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

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:

 

http://thebuildingcoder.typepad.com/blog/2017/06/sensors-bim-ai-revitlookup-and-fuzzy-comparison.htm...

 

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

 

https://stackoverflow.com/questions/7914830/what-is-the-difference-between-list-and-dictionary-in-c-...

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 11 of 11
DavidWoodCT
in reply to: jeremytammik

DavidWoodCT
Enthusiast
Enthusiast

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.36.78.0);

var CorTwo = new XYZ(7.9, 4.78.3);
            
myList.Add(CorOne);
myList.Add(CorTwo);


TaskDialog.Show("Debug Coordinate", myList[1].ToString());

TaskDialog.Show("Debug Coordinate", myList[2].ToString());

 

0 Likes

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.36.78.0);

var CorTwo = new XYZ(7.9, 4.78.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.

Post to forums  

Autodesk Design & Make Report