Raku中程序化生成half-winds罗盘风向点的更优实现咨询
更简洁的程序化生成方案
现有实现的冗余来自手动拆分各层方位数组、硬编码中间方位集合。基于Raku的列表索引、交错操作特性,可以写一个通用的方位展开逻辑,从最基础的4个 cardinal 方位出发,自动逐层生成对应方位集合,不需要硬编码任何中间数组。
half-wind 最简实现
# 仅保留最基础的顺时针排列 cardinal 方位 my @cardinal = <N E S W>; # 通用方位展开函数:在循环相邻方位间插入中间方位 sub expand(@points) { my $total = @points.elems; my @mid = (^$total).map(-> $i { my $current = @points[$i]; my $next = @points[($i + 1) % $total]; # 环接的最后一对(最后一个方位与第一个方位相邻),反向拼接避免生成无效字符串 $i == $total - 1 ?? ($next ~ $current) !! ($current ~ $next) }); # 原方位与中间方位交错,得到下一级完整方位列表 (@points Z @mid).flat } # 逐层展开:4个 cardinal → 8个 ordinal →16个 half-wind my @ordinal = expand(@cardinal); my @half-winds = expand(@ordinal);
输出校验
@ordinal结果为[N NE E SE S SW W NW],与原有实现完全一致@half-winds结果为[N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW],与硬编码的目标列表完全匹配
quarter-wind 扩展实现
仅需扩展展开函数的自定义中间方位生成规则,即可在half-wind基础上自动生成32个标准quarter-wind方位,无需额外硬编码:
# 支持自定义中间方位生成规则的扩展版本 sub expand-with-rule(@points, &mid-generator) { my $total = @points.elems; my @mid = (^$total).map(-> $i { my $current = @points[$i]; my $next = @points[($i + 1) % $total]; $i == $total - 1 ?? &mid-generator($next, $current) !! &mid-generator($current, $next); }); (@points Z @mid).flat } # 从half-wind生成quarter-wind的规则:采用标准 "X by Y" 命名规范 my @quarter-winds = expand-with-rule(@half-winds, -> ($a, $b) { $a ~ 'b' ~ $b.substr(*-1) });
方案对比优势
- 代码量减少约60%,不需要手动维护@cards、@odds、@mids 等中间变量
- 逻辑通用,只要调整中间方位的生成规则,就可以支持任意细分层级的方位生成,不存在硬编码偏移
- 输出结果与原有实现、标准罗盘方位列表完全一致
内容的提问来源于stack exchange,提问作者librasteve
相关产品推荐
相关产品推荐

