OK, it generates a not-so-special, case-sensitive Dictionary.
But I do wish it would generate a subclass instead so we can tell within the debugger or test for its case-sensitivity in code.
OK, it generates a not-so-special, case-sensitive Dictionary.
But I do wish it would generate a subclass instead so we can tell within the debugger or test for its case-sensitivity in code.
That’s a nice tip too.
Could you not add a boolean property CaseSensitiveCompare and implement the Text.Compare in a dictionary subclass with
If CaseSensitiveCompare
Yes, but that doesn’t help when parsing JSON.
What a great find Kem!
I’ve created a subclass imaginatively called CaseSensitiveDictionary
which acts as a drop-in replacement for the Xojo.Core.Dictionary
class with the exception that iterating through it requires a slight change:
dim d as new CaseSensitiveDictionary
for each entry as Xojo.Core.DictionaryEntry in d.data
' Do something
next entry
Here’s the class:
[code]Methods
Function Clone() As CaseSensitiveDictionary
dim c as new CaseSensitiveDictionary
c.data = data.Clone
return c
End Function
Sub Constructor()
self.data = Xojo.Data.ParseJSON( “{}” )
End Sub
Function Count() As Integer
return data.Count
End Function
Function HasKey(key As Auto) As Boolean
return data.HasKey(key)
End Function
Function Lookup(key As Auto, defaultValue As Auto) As Auto
return data.Lookup(key, defaultValue)
End Function
Sub Remove(key As Auto)
data.Remove(key)
End Sub
Sub RemoveAll()
data.RemoveAll()
End Sub
Function Value(key As Auto) As Auto
return data.Value(key)
End Function
Sub Value(key As Auto, Assigns value As Auto)
data.Value(key) = value
End Sub
Properties
data As Xojo.Core.Dictionary[/code]
It would seem fairly easy to EncodeBase64 the key, so any dictionary becomes case sensitive, not just Xojo.Code.Dictionary, but also classic Dictionary.
A subclass seems easy enough to create, based on that principle.
You can use Hex, not Base64, as the latter is a case-sensitive too.
If the trick in the original post still works I feel like it’d just be easier to do the trick than subclass dictionary!
The trick does still work (thankfully). The advantage of a subclass is that it prevents you from accidentally forgetting to use the hack when you instantiate a new Dictionary.
I’ve been playing around with this today and the trick still works. I wonder if there’s any re-assurance from Xojo that this will always be the case? I tried to subclass Xojo.Core.Dictionary and implement the CompareKeys event handler myself but quite frankly it seems to be a HUGE amount of work to support comparisons between all different key types. I just feel a little nervous deploying this code if Xojo breaks it in the next release…
Other than the Xojo.* stuff being deprecated eventually, I don’t see why this would ever change. The JSON spec calls for case-sensitive keys.
BTW, I implemented a case-sensitive Dictionary subclass here:
http://www.mactechnologies.com/index.php?page=downloads#case_sensitive_dictionary
Good point Kem. I think I will trust itll survive. Im well known for unnecessarily re-inventing the wheel…
UPDATE: With API 2, you can do the same:
var caseSensitiveDict as Dictionary = ParseJSON( "{}" )
Regarding your comment about being able to tell if it’s case-sensitive, we can’t actually tell that. You could (for instance) have a delegate which only checked for case-sensitivity on works that start with a-m, but not with ones that start with n-z, and we’d have no way to know that. Nor are keys always strings.
FYI, this no longer works (as of Xojo 2021 r2.1) for Text
keys. They are now case-insensitive even with this “hack”.
A JSONItem should be Case Sensitive by now since the JSON spec says so.
Perhaps it can be converted back to a dictionary ?
Notes (from the docs):
http://documentation.xojo.com/api/text/json/jsonitem.html
Names must be Strings, must be unique within an object and are case-sensitive.
Inspired by @Kem_Tekinay, I have written my own API 2.0 dictionary replacement called BetterDictionary
that can be case sensitive or case insensitive (set at instantiation). You can find it within my (new) Xojo-Collections repo.
It has the added advantage that it allows you to mix and match String
and Text
keys whilst considering them equivalent. I needed this as my current project uses Text
throughout and I kept getting caught out by the fact that there is no way in the IDE to write a Text
literal. It essentially works around this “bug”:
Var t As Text = "key1"
Var d As New Dictionary("key1" : Nil)
If d.HasKey(t) Then
Break // Never gets here but the code reads like it should.
Else
Break
End If