Sort SortedDictionary by Value

Sort SortedDictionary by Value

C_Haines_ENG
Collaborator Collaborator
720 Views
8 Replies
Message 1 of 9

Sort SortedDictionary by Value

C_Haines_ENG
Collaborator
Collaborator

Hello again!

 

I cant seem to sort a "sorted dictionary" as I cant define the types and iComparers. 

 

Does anyone know how to do this?

 

Dim oLib as New SortedDictionary(Of String, Double)

oLib.Add("Apple",1)
oLib.Add("Orange",5)
oLib.Add("Banana",2)

oLib.OrderBy(Function(x, y) x.Value.CompareTo(y.Value))
0 Likes
Accepted solutions (1)
721 Views
8 Replies
Replies (8)
Message 2 of 9

Andrii_Humeniuk
Advisor
Advisor
Accepted solution

Hi @C_Haines_ENG . If you need to sort by value, you should do it like this:

 

Dim oLib As New SortedDictionary(Of String, Double)

oLib.Add("Apple",1)
oLib.Add("Orange",5)
oLib.Add("Banana",2)

oLib.OrderBy(Function(x) x.Value)

For Each key In oLib
	Logger.Info(key.Key & " - " & key.Value)
Next

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 3 of 9

C_Haines_ENG
Collaborator
Collaborator

I swear I tried that exact string 40 times. Oh well, thank you!

Message 4 of 9

C_Haines_ENG
Collaborator
Collaborator

Would you believe its because I DID use that, but you cant use a SortedDictionary with any values that are the same. 

 

Welp, there goes my entire plan!

 

Oh and you cant sort a normal Dictionary. Fantastic language. 

 

0 Likes
Message 5 of 9

C_Haines_ENG
Collaborator
Collaborator

"At least one object must implement IComparable."

 

Also good to note, even unique "objects" are all considered the exact same thing no matter the type when you try to add them to a Sorted Dictionary. 

 

VB.Net sucks. 

 

 

0 Likes
Message 6 of 9

jjstr8
Collaborator
Collaborator

@C_Haines_ENG :  All Dictionaries must have unique Keys.  In your case, the Keys are the fruit names, the Values are the numbers.  In a SortedDictionary they are automatically sorted by the Key as they are added.  OrderBy is a LINQ method that returns another collection.  It does not alter your SortedDictionary.  In your code and @Andrii_Humeniuk's code, that return value is ignored.  Since the ascending order of the keys and the values are the same, it appeared to sort, but nothing changed.  What are you ultimately trying to do?  You may just be using the wrong type of collection.

0 Likes
Message 7 of 9

C_Haines_ENG
Collaborator
Collaborator

I am collecting Balloons and and their root node position and then sorting them so I can shift overlapping ones out of the way. 

 

I switched to a List(Of Balloon) but it doesn't store the node positions but since I'm accessing an object I can get those values after the fact.

 

The issue with the SortedDictionary is that its immediately forcing the compare on the keys, and since my Key is an object, ICompare cannot evaluate them, and therefore wont add.

0 Likes
Message 8 of 9

jjstr8
Collaborator
Collaborator

You might want to create a wrapper class to store the original Balloon object, as well as the location and anything else helpful.  Here's a "greatly simplified" example where the Balloon is a string, not the Inventor object.  Let me know if this makes sense.  The function used in the OrderBy can be pretty much whatever you want.  I'm not sure how you're evaluating overlap.

 

    Public Class BalloonWrapper
        Public Property Balloon As String
        Public Property NodeX As Integer
		Public Property NodeY As Integer
    End Class
	
	Sub Main()
        Dim BalloonList As New List(Of BalloonWrapper) From {
            New BalloonWrapper With {.Balloon = "Apple", .NodeX = 3, .NodeY = 4},
            New BalloonWrapper With {.Balloon = "Orange", .NodeX = 1, .NodeY = 0},
            New BalloonWrapper With {.Balloon = "Banana", .NodeX = 2, .NodeY = 8}
        }
		
        Dim SortedByNodeX = BalloonList.OrderBy(Function(b) b.NodeX)
        For Each item In SortedByNodeX
            Logger.Info(item.Balloon & " - " & item.NodeX & "," & item.NodeY)
        Next
		Logger.Info("")
		
		Dim SortedByNodeY = BalloonList.OrderBy(Function(b) b.NodeY)
        For Each item In SortedByNodeY
            Logger.Info(item.Balloon & " - " & item.NodeX & "," & item.NodeY)
        Next
		Logger.Info("")
		
		Dim SortedByBalloon = BalloonList.OrderBy(Function(b) b.Balloon)
        For Each item In SortedByBalloon
            Logger.Info(item.Balloon & " - " & item.NodeX & "," & item.NodeY)
        Next
    End Sub

 

Message 9 of 9

Andrii_Humeniuk
Advisor
Advisor

If you need to sort multiple values ​​then the proposed @jjstr8 option with the creation of a separate class is the best. Placing your class instances in a List object will then make it very easy to sort them. Here is an example:

Dim BalloonList As New List(Of BalloonWrapper)
BalloonList = BalloonList.OrderBy(Function(s) s.NodeX).ThenBy(Function(s) s.NodeY).ToList()

 

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes