Numeric strings don’t work in Dictionary lookup

Possible new bug, if I have a dictionary where the key values are number strings e.g. “370” then when I use

key = “370”
Value = Dict[key]

I get returned the 370th entry in Dict and not the entry where the key is “370”

What platform is this, and can I see a more complete sample? e.g. how is Dict defined and populated?

Hi - this is the same project I sent you the source code for earlier regarding bugs://84684. The relevant parts are

open class TEngineMetric {
public var description: String!
public var relevant: String!
}

var engine_metric_table: Dictionary<String!,TEngineMetric!>! = Dictionary<String!,TEngineMetric!>()
var engine_metric_data: TEngineMetric! = TEngineMetric()

//  Build SAP metric description table

filepath = tRefFiles.Text + "\\sap-metrics.csv"
sapLicenses = try File.ReadAllText(filepath)
rows = sapLicenses.components(separatedBy: "\n")
for row in rows {
	let columns = row.components(separatedBy: ",")
	engine_metric_data.description = columns[1]
	engine_metric_data.relevant = columns[2]
	engine_metric_table.Add(columns[0], engine_metric_data)
}

var metric_clean: String
metric_clean = engine_data.Value.engine_sub_code.TrimStart("0") /* String "0370" converted to "370" */
engine_metric = engine_metric_table[metric_clean].description
metric_relevant = engine_metric_table[metric_clean].relevant

The last two lines return the 370th item in the dictionary not the item where the key is “370” which is much earlier in the sequence as the table doesn’t have all numbers from 1…whatever

Hm, this works for me as expected:

let x = Dictionary<String!,String!>()

x["2"] = "two"
x["370"] = "threeseventy"

writeLn("x[370] \(x["370"])")

as does using

x.Add("370", "threeseventy")

instead. are you sure your columns[] value are correct?

Pretty sure, if I put a watch on the variables when loading the engine_metric_table I can see this sort of thing:

Name Value Type
:arrow_forward: engine_metric_table Count = 45 Dictionary<String,MainForm.TEngineMetric>
columns[0] “370” String
columns[1] “Number of Gateway calls (ODC) per year” String
columns[2] “N\r” String

and

Name Value Type
[45] {[“370”, {MainForm.TEngineMetric}]} KeyValuePair<String,MainForm.TEngineMetric>
Key “370” String
◢ Value {MainForm.TEngineMetric} MainForm.TEngineMetric
@_description “Number of Gateway calls (ODC) per year” String
@_relevant “N\r” String
description “Number of Gateway calls (ODC) per year” String
relevant “N\r” String

This shows they key is a string version of a number OK.

When I put a similar watch on the retrieval I get

Name Value Type
metric_clean “370” String
engine_metric_table[metric_clean] {MainForm.TEngineMetric} MainForm.TEngineMetric
@_description “Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities” String
@_relevant “Y” String
description “Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities” String
relevant “Y” String

item 370 in the dictionary is

Name Value Type
[370] {[“5259”, {MainForm.TEngineMetric}]} KeyValuePair<String,MainForm.TEngineMetric>
Key “5259” String
◢ Value {MainForm.TEngineMetric} MainForm.TEngineMetric
@_description “Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities” String
@_relevant “Y” String
description “Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities” String
relevant “Y” String

can i get the file you are loading, so I can see/debug the myself?

Sure, can I send as a DM somehow?

Also, what type is Dictionary — there’s at least there potentials, depending o whats in your imports — System.Collections.Generic.Dictionary, RemObjects.Elements.RTL.Dictioanry or Swift.Dictionary.

Sure just click on my name and you can send me a DM no-one else can see.

Has to be import System.Collections.Generic, since Swift doesnt have Add() and RemObjects.Elements.RTL .File doesnt have ReadAllText :wink:

I’m using System.Collections.Generic, sending you the file I am loading via DM

1 Like

Odd indeed, I get

engine_metric_table["50"] Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities
engine_metric_table["51"] Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities
engine_metric_table["370"] Usage Indicator Overtake and Undertake Quantities Billing for German Energy Utilities

I.e… i get the LAST value, no matter what value I ask for…

oh, duh?

var engine_metric_data: TEngineMetric! = TEngineMetric()

for row in rows {
    ...
    engine_metric_data.description = columns[1]
    engine_metric_data.relevant = columns[2]
    engine_metric_table.Add(columns[0], engine_metric_data)
}

you ar creating ONE copy of the TEngineMetric class. in each iteragtion, you update it to the data from the current row, and add it (the same copy) to the dictionary, under a new key. your dictionary now has ~500 entries with different keys, all pointing to the same class ;).

you will need to move the

var engine_metric_data: TEngineMetric! = TEngineMetric()

into the for loop, so that you create 500 separate instances.

ConsoleApplication8 1.bugreport.zip (55.6 KB)

I will now go away and bang my head against my desk ~500 times. Sorry :woozy_face:

Thanks for spotting that

No worries, took me waaaay to long to notice, it, too :wink: