Skip to content

Collect Node

Noogear edited this page Mar 16, 2026 · 4 revisions

集合操作

collect 节点用于遍历集合或数组变量,按条件筛选、计数或提取元素。

支持 ListSetCollectionMap 和 Java 数组(String[]int[] 等)。

基本格式

- collect: <collectionVariable>
  op: "<operation>"
  iterate: "values"           # Map 遍历模式(可选,详见下方)
  match:
    - check: "$it"
      op: "<operator>"
      value: <value>
  store: "resultVar"         # count/index/find/filter 必填
  on_fail:                   # exists/all 可选
    - action: "fallback"
字段 类型 必填 说明
collect String 集合变量名
op String 操作类型
iterate String Map 遍历模式:values(默认)、keysentries
match List 内联谓词子脚本(标准 check 节点列表,AND 关系)
store String 视操作 结果存储变量名
on_fail List 量词操作失败时执行的节点列表

操作类型

量词操作(影响控制流)

量词操作决定脚本是否继续执行后续节点,类似 check 的行为。

操作 取反 说明
exists !exists 是否存在至少一个匹配元素
all !all 是否全部元素都匹配
  • 条件成立:继续执行后续节点
  • 条件不成立:执行 on_fail(如果有),然后终止脚本
# 如果存在包含 "sword" 的物品,继续执行
- collect: items
  op: exists
  match:
    - check: "$it"
      op: "contains"
      value: "sword"
  on_fail:
    - action: "sendMessage"
      args: ["没有找到剑"]
    - return

# 如果所有分数 >= 60,继续执行
- collect: scores
  op: all
  match:
    - check: "$it"
      op: ">="
      value: 60
  on_fail:
    - action: "sendMessage"
      args: ["存在不及格分数"]

# 取反:如果不存在诅咒物品,继续执行
- collect: items
  op: "!exists"
  match:
    - check: "$it"
      op: "contains"
      value: "curse"

提取操作(短路,找到即停)

操作 store 类型 说明
index int 首个匹配元素的索引(-1 表示未找到)
find Object 首个匹配元素对象(null 表示未找到)
# 查找第一个等于 "sword" 的元素索引
- collect: items
  op: index
  store: "foundIndex"
  match:
    - check: "$it"
      op: "=="
      value: "sword"

# 查找第一个以 "sw" 开头的元素
- collect: items
  op: find
  store: "foundItem"
  match:
    - check: "$it"
      op: "starts_with"
      value: "sw"

聚合操作(全量扫描)

操作 store 类型 说明
count int 匹配元素的数量
filter List 所有匹配元素组成的列表
# 统计包含 "s" 的元素数量
- collect: items
  op: count
  store: "matchCount"
  match:
    - check: "$it"
      op: "contains"
      value: "s"

# 筛选出所有包含 "s" 的元素
- collect: items
  op: filter
  store: "filteredItems"
  match:
    - check: "$it"
      op: "contains"
      value: "s"

match 谓词

match 是一个内联谓词子脚本——使用标准的 check 节点语法。$it 指代当前迭代的元素本身。

多个 check 之间为 AND 关系——元素必须满足所有条件才算匹配。

# 同时满足:包含 "o" 且以 "d" 结尾
- collect: items
  op: exists
  match:
    - check: "$it"
      op: "contains"
      value: "o"
    - check: "$it"
      op: "ends_with"
      value: "d"

属性访问

通过 check: 指定属性路径(而非 $it),可以访问元素的子属性进行比较:

match:
  - check: "type.name"       # 访问 element.getType().getName()
    op: "=="
    value: "DIAMOND_SWORD"
  - check: "amount"          # 访问 element.getAmount()
    op: ">"
    value: 5
check 说明
$it 元素本身(默认)
fieldName 单级属性,等价于 element.getFieldName()
a.b.c 多级属性链,等价于 element.getA().getB().getC()

属性路径规则:

  • . 分隔多级属性,例如 "type.name" 等价于 Java 的 item.getType().getName()
  • 属性名对应 getter 方法(自动加 get 前缀,布尔属性也支持 is 前缀)

示例:检查背包物品

variables:
  inventory: "player.inventory"   # List<ItemStack>

flow:
  # 检查是否存在 type.name == "DIAMOND_SWORD" 且 amount > 5 的物品
  - collect: inventory
    op: exists
    match:
      - check: "type.name"
        op: "=="
        value: "DIAMOND_SWORD"
      - check: "amount"
        op: ">"
        value: 5
    on_fail:
      - action: "sendMessage"
        args: ["未找到足够数量的钻石剑"]
      - return

  # 筛选所有耐久低于 20 的工具
  - collect: inventory
    op: filter
    store: "damagedItems"
    match:
      - check: "durability"
        op: "<"
        value: 20

可以在同一个 match 列表中混合使用 $it 和属性访问:

match:
  - check: "$it"             # 先检查元素非空
    op: "!null"
  - check: "name"            # 再检查属性
    op: "contains"
    value: "Elite"

操作符完整列表 → 操作符参考


支持的集合类型

类型 说明
List<T> 标准列表
Set<T> 集合
Collection<T> 任意 Collection
T[] Java 数组(String[]int[]double[] 等)
Map<K, V> 默认遍历 values,可通过 iterate 字段切换

引擎自动推断元素类型,为匹配条件选择正确的比较方式。


Map 遍历模式

当集合变量为 Map 类型时,可通过 iterate 字段控制遍历方式:

模式 iterate $it 指代 说明
值遍历 values(默认) Map 的 value 向后兼容的默认行为
键遍历 keys Map 的 key 遍历所有键
键值对遍历 entries 不可用 使用 $key$value 双变量

默认模式(values)

不指定 iterate 时,默认遍历 Map 的值集合:

- collect: scoreMap
  op: exists
  match:
    - check: "$it"
      op: ">="
      value: 90

键遍历模式(keys)

- collect: metadata
  op: exists
  iterate: keys
  match:
    - check: "$it"
      op: "starts_with"
      value: "buff_"

键值对遍历模式(entries)

entries 模式下,match 中使用 $key$value 代替 $it 来分别引用当前键值对的键和值:

# 检查是否存在 key 以 "att" 开头的条目
- collect: stats
  op: exists
  iterate: entries
  match:
    - check: "$key"
      op: "starts_with"
      value: "att"

# 统计 value >= 70 的条目数量
- collect: stats
  op: count
  iterate: entries
  store: "highCount"
  match:
    - check: "$value"
      op: ">="
      value: 70

# 组合条件:key 和 value 同时满足
- collect: stats
  op: exists
  iterate: entries
  match:
    - check: "$key"
      op: "starts_with"
      value: "att"
    - check: "$value"
      op: ">="
      value: 90

取反规则

仅量词操作(existsall)支持 ! 前缀取反:

操作 含义
exists 至少一个匹配 → 通过
!exists 没有任何匹配 → 通过
all 全部匹配 → 通过
!all 至少一个不匹配 → 通过

countindexfindfilter 不支持取反


完整示例

库存检查

id: "inventory-checker"
event: "com.example.TradeEvent"

variables:
  items: "player.inventory"

flow:
  # 1. 必须有稀有物品
  - collect: items
    op: exists
    match:
      - check: "$it"
        op: "contains"
        value: "rare"
    on_fail:
      - action: "sendMessage"
        args: ["背包中没有稀有物品"]
      - return

  # 2. 统计稀有物品数量
  - collect: items
    op: count
    store: "rareCount"
    match:
      - check: "$it"
        op: "contains"
        value: "rare"

  # 3. 筛选所有稀有物品
  - collect: items
    op: filter
    store: "rareItems"
    match:
      - check: "$it"
        op: "contains"
        value: "rare"

  - action: "processTrade"
    args: ["{rareCount}"]

分数验证

id: "score-validator"
event: "com.example.ExamEvent"

variables:
  scores: "student.scores"

flow:
  # 全部科目必须及格
  - collect: scores
    op: all
    match:
      - check: "$it"
        op: ">="
        value: 60
    on_fail:
      - action: "sendMessage"
        args: ["存在不及格科目"]
      - return

  - action: "grantDiploma"

多条件匹配

id: "advanced-filter"
event: "com.example.SearchEvent"

variables:
  players: "server.onlinePlayers"

flow:
  # 查找第一个满足所有条件的玩家
  - collect: players
    op: find
    store: "target"
    match:
      - check: "$it"
        op: "!null"
      - check: "$it"
        op: "instanceof"
        value: "org.bukkit.entity.Player"

  - check: target
    op: "!null"
    on_fail:
      - return

  - action: "sendMessage"
    args: ["找到目标玩家"]

Clone this wiki locally