Verse Wiki — 写给蓝图作者的 Verse 手册
拓展 · EXTRA

遍历 map:Key->Value 语法与手动计数器

同样是「多给你一位」的遍历写法,数组给的是数字下标,map 给的却是「键」。想在遍历 map 时同时拿到「这是第几个」?官方没给捷径——这一页讲清这处不对称(蓝图里 For Each Loop (Array) 给你 Index、For Each Loop (Map) 给你 Key,正是同一处区别),以及社区公认的补法。

一、同一个箭头,两种收获

第 14 课学过数组的带下标遍历(蓝图 For Each Loop (Array) 的 Array Index 引脚),从 0 开始数。map 也有同样「多给一位」的写法:for (Key -> Value : Map):——但注意,这里多给的是,不是序号,正好对应蓝图 For Each Loop (Map) 的 Key 引脚。写法长得一模一样,含义完全两回事:数组的「地址」天生是数字下标,map 的「地址」是你自己定的键(字符串、整数都行),所以这里送上来的自然是键。

shop_device.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }

shop_device := class(creative_device):

    # 商店价目表:键是商品名,值是价格
    Prices:[string]int = map{"药水" => 50, "木剑" => 120, "金币袋" => 300}

    OnBegin<override>()<suspends>:void =
        for (Name -> Price : Prices):
            Print("{Name} 售价 {Price} 金币")

读图翻译:Prices 是一张价目表(蓝图里的 Map,键是商品名、值是价格)。这段就是 For Each Loop (Map):每轮从 Key 引脚拿到商品名 Name、从 Value 引脚拿到价格 Price,用 Print String 打成「__ 售价 __ 金币」。

这段代码里 Name 依次是各个商品名,Price 是对应价格。省事归省事,但假如需求是「打印第 1 件、第 2 件、第 3 件」呢?数组遍历顺手就有的序号,map 这边——没有。

二、要序号?官方也没捷径,自己数

这不是你没找到节点。Epic 开发者论坛上有人专门发帖问「用 for 遍历 map 时能不能顺便拿到一个序号」,这个帖子至今零回复——官方和社区都没有内建办法,因为它确实不存在。能用的做法就是发帖人自己记下的那个土办法:循环外面先建一个计数变量,循环体里每轮手动加一。

counted_shop_device.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }

counted_shop_device := class(creative_device):

    Prices:[string]int = map{"药水" => 50, "木剑" => 120, "金币袋" => 300}

    OnBegin<override>()<suspends>:void =
        # map 遍历没有内建序号:循环外开计数器,体内手动 +1
        var Counter:int = 0
        for (Name -> Price : Prices):
            set Counter += 1
            Print("第{Counter}件:{Name} 售价 {Price} 金币")

读图翻译:循环外先建一个整数变量 Counter = 0(蓝图里的 Integer 变量),For Each Loop (Map) 每轮先用一个 Set 节点把 Counter 加一(set Counter += 1),再用 Print String 打「第 __ 件:__ 售价 __」。这正是蓝图里给 ForEach 手动配一个计数变量的老套路。

两个细节值得留意。其一,set Counter += 1(那个 Set 节点)要放在循环体里,别塞进 for 的括号筛选里——筛选必须能试完收回,把「做了就算数」的 Set 放进去,要么领效果错误(Compile 报红),要么在某轮没通过时被一起收回、白加,徒增混乱。其二,这个计数器数的是「真正跑过的轮次」:如果 for 带了筛选,被跳过的那几轮不会加一,序号照样连续——这通常正合你意。

三、顺序能信吗?先实测再托付

最后一个自然的问题:map 遍历吐出这些键值对的顺序是什么?常见的观察是跟写入顺序一致,但请当心——官方文档并没有把遍历顺序写成一条硬承诺,依赖它,就像把玩法押在一句口头约定上。如果你的玩法(排行榜、商店排序)依赖确定顺序,稳妥做法有二:要么先在你的目标版本里实测一遍确认,要么干脆别赌——先把所有键收进一个数组、按需排好序,再逐个用键去 map 里取值(蓝图里 Map 的 Find 节点),顺序从此攥在自己手里。

另外别忘了第 14 课的「快照」:for 认的是循环开跑那一刻的 map 样子,循环体里就算你用 Set 节点往同一个 map 变量里塞新键值,本轮遍历也不会跟着变。

四、随堂小测

用 For Each Loop (Map) 遍历一个「键是文字、值是整数」的 map 时,多给你的那一位 K 是什么?

来源

本文整理自 Epic 开发者论坛与官方文档:Iterate map variable in a for loop and index counter ↗Array in Verse ↗