Case Sensitive Dictionary Code Example

I’d like to replace my previous deprecated code (using Xojo.core.dictionary) with the new code for a case sensitive dictionary. A previous thread https://forum.xojo.com/t/case-sensitive-dictionary/50435 didn’t quite get me to the answer and the reference manual is a bit light on detail.

Can anyone provide a simple code example to set up and use case sensitivity with keyComparison?

Or is there a simple way of encoding the key so that it becomes case sensitive?

var d as Dictionary = ParseJSON( "{}" )
2 Likes

As I don’t understand how that works, I might avoid it lest I return to it later and wonder “what the heck is that?”

I’ve added encodeHex to each key instead - it probably slows things down a little but hopefully works.

…ah, I see now that parseJson always returns a case sensitive dictionary.

Right, because json is case sensitive. That’s the most convenient way to do it, especially when debugging, and also the best performance.

2 Likes

You can use memoryblocks instead of strings.

1 Like

https://drive.google.com/file/d/108RI2XDAy2l5Dy-QHdefsogJ2fGXGAYY/view?usp=sharing

// BinaryDictionary By Rick A.
// 2021-12-23 V1.0

Protected Class BinaryDictionary Inherits Dictionary

		Protected Method BinaryCompare(v1 As Variant, v2 As Variant) As Integer

		  Var m1, m2 As MemoryBlock
		  m1 = v1.StringValue // ignore the real value, just get the nearest equivalent string of bytes
		  m2 = v2.StringValue // For example, Nil becomes ""
		  Return If( m1=m2, 0, If(m1>m2, 1, -1) )
		  
		End Method


		Method Constructor()

		  Super.Constructor(AddressOf BinaryCompare)
		  
		End Method
		
End Class

I’d expect this to be slow as the number of keys grows. Using StrComp would be faster.

And still not as fast as a JSON-based Dictionary. But I haven’t tested any of these contentions.

I do expect being better than the JSON one because it should not carry the extra overheads that JSON needs, like needing escaped chars (like \uHEX) for keys and values for unsafe values. It’s safer than trying to apply StrComp assuming the variants are all strings, and wont crash if one of those keys were Nil for example. Adding extra ifs just for that will slow it a bit too, so I opted for not.
This version has some strengths, that I like and need, but I would like to see some speed measures just out of curiosity too.

Ok, I did a small test and seems that the JSON one is like 10x faster. Probably the conversion to memoryblocks plus compare invocations are high costly.

1 Like

You don’t even need to overload any functions.

Dim p as memoryblock  = stringKey
dictionary.value( p ) = value

You may even be able to use cType or even inline cast a string to a memoryblock.

The expected delegate uses variants, not on my control. I don’t know any faster way of making it compatible than MemoryBlock = Variant.StringValue

Any attempts I did, or failed to be accepted, or did not add any speed.

I never tested it for speed, I just had to stuff some values into a dictionary. I didn’t over load any of the dictionary methods / events. Just made sure all my keys were memoryBlocks.

It was some time ago I did this, so maybe it doesn’t work with newer versions of Xojo.

I did a quick test in old RB:

  dim mb1 as MemoryBlock = "a"
  dim mb2 as MemoryBlock = "A"
  dim s as String = "a"
  dim mb3 as MemoryBlock = s
  dim d as new Dictionary
  d.Value (mb1) = 1
  d.Value (mb2) = 2
  d.Value (mb3) = 3
  dim c as Integer = d.Count
  break

Here, I would expect that mb1 and mb3, since they contain the same string “a”, end up using the same keyed entry in the dict, and hence d.Count should be 2. But it comes out as 3. Meaning that the MemoryBlock method does not work because the Dictionary matching only compares the memoryblock’s address for equality, not their contents.

2 Likes