一帆风顺的你 發表於 2024-3-12 20:07:00

Delphi TDictionary字典类

<p>TDictionary <span style="color: rgba(255, 0, 0, 1)">是一个开放哈希表</span>,支持泛型,并提供了以下常用属性和方法:</p>
<p>属性:</p>
<p>Count:返回字典中元素的数量。<br>Keys:返回字典中所有键所组成的动态数组。<br>Values:返回字典中所有值所组成的动态数组。</p>
<p>方法:</p>
<p>Add:向字典中添加一个键和其对应的值。<br>Clear:清空字典中的所有元素。<br>ContainsKey:判断字典中是否包含指定的键。<br>ContainsValue:判断字典中是否包含指定的值。<br>Remove:从字典中删除指定的键以及对应的值。<br>TryGetValue:尝试从字典中获取指定键所对应的值。<br>GetEnumerator:返回一个用于枚举字典中元素的对象(TDictionary&lt;_,_&gt;.TPairEnumerator 类型)。</p>
<p>除此之外,TDictionary 还提供了一些其他方法和事件,如 `OnChange`, `TrimExcess`, `IndexOfKey` 和 `IndexOfValue`。具体用法可以参考 Delphi 文档或自行搜索。</p>
<p>声明与创建时,需要指明K与V的数据类型,比如:</p>
<div class="cnblogs_code">
<pre>var<span>
    dic: TDictionary&lt;string, integer&gt;<span>;
begin<span>
    dic := TDictionary&lt;string, Integer&gt;.Create<span>;
end;</span></span></span></span></pre>
<div>&nbsp;</div>
</div>
<p>示例一:对数据(数组)去重.以下代码实现了对数组元素的去重:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> RemoveDuplicates 函数接受一个字符串数组作为输入,使用字典来记录数组中的唯一元素,并返回去重后的数组。</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> RemoveDuplicates(<span style="color: rgba(0, 0, 255, 1)">const</span> arr: TArray&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;): TArray&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
dic: TDictionary</span>&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, Boolean&gt;; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 声明 TDictionary 用于记录唯一元素,值为 Boolean 表示只需记录键而不需值</span>
value: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 用于遍历输入数组中的元素</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
dic :</span>= TDictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, Boolean&gt;.<span style="color: rgba(0, 0, 255, 1)">Create</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建字典</span>
<span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> value <span style="color: rgba(0, 0, 255, 1)">in</span> arr <span style="color: rgba(0, 0, 255, 1)">do</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 遍历输入数组</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span>
      <span style="color: rgba(255, 0, 0, 1)">if not dic.ContainsKey(value) then // 如果字典中不包含当前值
      begin
      dic.Add(value, True); // 将当前值添加到字典中,值设置为 True
      end;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

    Result :</span>= dic.Keys.ToArray; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将字典的键(唯一元素)转换为数组并返回</span>
<span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    dic.Free; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 释放字典对象</span>
<span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>注意,重复添加字典中已存在的KEY 会报错,所以需要用ContainsKey方法来判断一下当前KEY是否已经存在,如果没有再添加进字典.</p>
<p>上面的红字部分代码稍微修改一下,也可以用来对相同key的值的累加:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">if</span> dic.ContainsKey(sKey) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
   dic :</span>= dic +<span style="color: rgba(0, 0, 0, 1)"> SuNumber
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
   dic.Add(sKey, SuNumber);</span></pre>
</div>
<p>示例二: 对字典进行排序.这里注意一下,<strong><span style="color: rgba(255, 0, 0, 1)">字典是一个开放哈希表,无法直接排序.</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span> TForm2.SortDic(dic: TDictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, integer&gt;<span style="color: rgba(0, 0, 0, 1)">): TStringList;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> sl := TStringList.<span style="color: rgba(0, 0, 255, 1)">Create</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> <span style="color: rgba(0, 0, 255, 1)">var</span> k <span style="color: rgba(0, 0, 255, 1)">in</span> dic.keys <span style="color: rgba(0, 0, 255, 1)">do</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      sl.Add(k </span>+ <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">@</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> IntToStr(dic));
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
    sl.Sorted :</span>=<span style="color: rgba(0, 0, 0, 1)"> true;  //对TStringList进行自动排序
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    result :</span>=<span style="color: rgba(0, 0, 0, 1)"> sl;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">使用</span>

<span style="color: rgba(0, 0, 255, 1)">var</span> sl:=TStringList.<span style="color: rgba(0, 0, 255, 1)">Create</span><span style="color: rgba(0, 0, 0, 1)">;
sl:</span>=SortDic(dic)</pre>
</div>
<p>上面的代码,把字典里的K,V用"@"符号拼接了起来,塞进一个TStringList类里.字典不可以排序,但是TStringList可以啊,只是在使用里,需要SPLIT一下元素才行</p>
<div class="cnblogs_code">
<pre>sl :=<span style="color: rgba(0, 0, 0, 1)"> SortDic(dic);
k :</span>= <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> <span style="color: rgba(0, 0, 255, 1)">var</span> key <span style="color: rgba(0, 0, 255, 1)">in</span> sl <span style="color: rgba(0, 0, 255, 1)">do</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 0, 255, 1)">var</span> temparr := key.Split([<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">@</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]);
    ws2.range[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">E</span><span style="color: rgba(128, 0, 0, 1)">'</span> + inttostr(k) + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">:K</span><span style="color: rgba(128, 0, 0, 1)">'</span> + inttostr(k)].value := VarArrayOf(,temparr[</span><span style="color: rgba(128, 0, 128, 1)">5</span>], temparr[<span style="color: rgba(128, 0, 128, 1)">1</span>], temparr[<span style="color: rgba(128, 0, 128, 1)">2</span>], <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">新刀具区</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, temparr[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">]]);
    k :</span>= k + <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>上面这段代码是把TStringList里面的数据写进EXCEL单元格里.</p><br><br>
来源:https://www.cnblogs.com/yoooos/p/18069111
頁: [1]
查看完整版本: Delphi TDictionary字典类