You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需命名位置参数,存储并排序函数混合参数后调用?

问题解决:Typst函数按数组参数排序调用且无需修改位置参数定义

问题背景

你定义了如下带位置参数(name)和命名参数的Typst函数:

#let monster(
  name, 
  desc: "", 
  strikes: 1, 
  hits_on: 3,
  points: (),
  attacks: 1,
  doc: []
) = {
  // 函数实现内容
}

你希望将多次调用该函数的参数存入数组,按name排序后批量调用函数,但现有实现需要为每个数组元素的位置参数name指定键名,且若使用..m展开操作还需将name设为可选——你不想给大量位置参数额外命名,也不想修改原函数的参数定义,询问如何实现需求。

你当前尝试的代码如下:

#let monsters = ( 
  (
    name: "Goblin",
    desc: "Small evil subserviant humanoid", 
    doc: lorem(20),
  ),  
  (
    name: "Orc", 
    doc: lorem(10),
    hits_on: 3,
  ),
  (
    name: "Wight",
    desc: "Sentient flesh-eating undead",
    strikes: 3,
    points: (
      [When taking a strike from a #monster, MR or be paralyzed for the scene.],
      [Loses a strike each turn spent exposed to sunlight.]
    )
  ),
  (
    name: "Zombie",
    strikes: 2, 
  ),
  (
    name: "Skeleton",
  )
).sorted(key: m => m.name).map(m => monster(..m)).join()

解决方案

无需修改原函数的参数定义,也不用调整数组元素的写法,只需修改map中的函数调用逻辑:手动提取name作为位置参数传递,再展开移除name后的剩余键值对作为命名参数。

修改后的代码如下:

#let monsters = ( 
  (
    name: "Goblin",
    desc: "Small evil subserviant humanoid", 
    doc: lorem(20),
  ),  
  (
    name: "Orc", 
    doc: lorem(10),
    hits_on: 3,
  ),
  (
    name: "Wight",
    desc: "Sentient flesh-eating undead",
    strikes: 3,
    points: (
      [When taking a strike from a #monster, MR or be paralyzed for the scene.],
      [Loses a strike each turn spent exposed to sunlight.]
    )
  ),
  (
    name: "Zombie",
    strikes: 2, 
  ),
  (
    name: "Skeleton",
  )
).sorted(key: m => m.name)
.map(m => monster(m.name, ..m.without("name")))
.join()

原理说明

  • m.name直接提取数组元素中的name值,作为monster函数的第一个位置参数传递,符合原函数的参数要求。
  • m.without("name")会生成一个移除了name键的新字典,再通过..展开操作将剩余键值对作为命名参数传递,避免了位置参数与展开的命名参数冲突。

这种方式既保留了你现有数组的写法,又不用修改原函数的参数结构,完美满足需求。

内容的提问来源于stack exchange,提问作者Matt Joiner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:44:56