如何基于集合常量创建预设元素的Delphi数组?
解决方法
Delphi 不支持直接用集合类型作为数组的下标,因为数组下标要求是有序的离散类型(比如枚举、连续字符/整数范围),而集合是无序的元素集合,无法和数组的有序索引一一对应。不过可以用以下几种更优雅的方式实现需求,避免冗余分支且不用重型容器:
方案1:自定义枚举映射(最接近你的理想写法)
先定义枚举类型对应目标字符,再通过枚举数组存储上标字符,最后做字符和枚举的转换:
type TTargetChar = (tc0, tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9, tcPlus, tcMinus); const TargetChars: array[TTargetChar] of Char = ('0','1','2','3','4','5','6','7','8','9','+','-'); SuperChars: array[TTargetChar] of Char = ('⁰','¹','²','³','⁴','⁵','⁶','⁷','⁸','⁹','⁺','⁻'); function SuperScript(c: Char): Char; var idx: Integer; begin idx := IndexOfChar(TargetChars, c); if idx <> -1 then Result := SuperChars[TTargetChar(idx)] else Result := c; end;
这里利用枚举的有序性,让SuperChars数组可以和目标字符一一对应,通过IndexOfChar快速查找位置,逻辑更统一。
方案2:合并数组+集合判断简化分支
如果不想用枚举,可以把目标字符和上标字符分别存为数组,配合集合判断简化代码:
const Digits = ['0'..'9']; Signs = ['+', '-']; DigitsAndSigns = Digits + Signs; SourceChars: array[0..11] of Char = ('0','1','2','3','4','5','6','7','8','9','+','-'); SuperChars: array[0..11] of Char = ('⁰','¹','²','³','⁴','⁵','⁶','⁷','⁸','⁹','⁺','⁻'); function SuperScript(c: Char): Char; var i: Integer; begin if CharInSet(c, DigitsAndSigns) then begin for i := Low(SourceChars) to High(SourceChars) do if SourceChars[i] = c then begin Result := SuperChars[i]; Exit; end; end; Result := c; end;
如果觉得循环效率不够,还可以把对应关系用字符范围优化,用case语句替代冗余分支,比原代码更简洁:
function SuperScript(c: Char): Char; const SuperDigits: array['0'..'9'] of Char = ('⁰','¹','²','³','⁴','⁵','⁶','⁷','⁸','⁹'); begin case c of '0'..'9': Result := SuperDigits[c]; '+': Result := '⁺'; '-': Result := '⁻'; else Result := c; end; end;
为什么你的理想写法无法编译?
Delphi 的数组下标类型必须是有序类型(枚举、整数、字符范围等),而DigitsAndSigns是集合类型(set of Char),集合是无序的元素集合,编译器无法确定集合中元素的顺序,也就无法和数组的有序元素一一对应,因此直接用集合作为数组下标是不被支持的。
内容的提问来源于stack exchange,提问作者Matej
相关产品推荐
相关产品推荐

