5

I have a TDictionary like

target_results : TDictionary<longint,double>;

After populating it I need to sort the results. I'm doing it like this

type
  TSearchResult = TPair<longint,double>;

var
 target_results_array : TArray<TSearchResult>;

target_results_array:= target_results.ToArray;
TArray.Sort<TSearchResult>(best_knowledge_search_results,
                    TComparer<TSearchResult>.Construct(
                              function(const L, R: TSearchResult): Integer
                              begin
                                if L.Value < R.Value then Result := 1 else if L.Value > R.Value then Result := -1 else Result := 0;
                              end
                    ));

It's all working as expected. My question is how do I dispose of the TDictionary and the TArray without any leaks? Currently I'm just doing

target_results.Free;
Miguel E
  • 1,316
  • 2
  • 17
  • 39
  • I don't understand why you use a dictionary. This looks like it should be TList. – David Heffernan Aug 04 '13 at 12:19
  • 3
    @DavidHeffernan I'm performing a bunch of queries to determine a final score. Each query brings a set of sub-total scores. I use TDictionary.AddOrSetValue to add a new entry or add the sub-total to the existing key. Would you say this is the most efficient structure to fit this? Thanks! – Miguel E Aug 04 '13 at 12:25
  • 1
    If you are performing key lookup then a dictionary is good. Of course, that aspect is not in the Q, hence my query. But it seems you've got the right data structure. – David Heffernan Aug 04 '13 at 12:32
  • 2
    Just to make clear: AddOrSetValue doesn't add the sub-total to the existing value, it will simply overwrite any existing value with the new sub-total. – Uwe Raabe Aug 04 '13 at 16:09
  • @UweRaabe Thanks. I'm using TryGetValue to retrieve a possible already existing value, before adding the sub-total. – Miguel E Aug 04 '13 at 19:53
  • This just reminds me how poor our Collections unit is. :-( This problem cries out for a default dictionary implementation. Even without one if we had a function that returned a specified value if a key wasn't found you could just do your totals as: target_results.Items(index) := target_results.get(index, 0) + subtotal. Actually since items has an exception we'd target_results.AddOrSetValue(index, target_results.get(index, 0) + 1). Yuck.. TDictionary needs a lot of work. We also need a sort function that takes a key value rather than a custom comparison function so you could sort in just 1 line – alcalde Aug 05 '13 at 06:04

1 Answers1

6

Since your data is longints and doubles, which are both value types, freeing the dictionary will work fine. Your array will contain a copy of the original values, and you don't need to worry about losing or corrupting anything.

If you had object types instead, and you had a TObjectDictionary that owned the objects, then you'd have to worry about this sort of thing, but for purely numeric data, you're fine.

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477