Bases-函数

函数

数据库中,函数可在工具栏中“筛选器”菜单下的高级筛选模式,或是“属性”菜单下的“添加函数”中添加,以处理来自笔记属性的数据。欲知更多有关如何使用函数的知识,请参看数据库语法

全局函数外,大多数函数都与用户想要处理的值的类型相关:

背景知识

在正式开始学习函数之前,需要对下文涉及到的一些计算机术语进行简单的介绍,已有涉猎者请直接跳过。

[!NOTE] 什么是字符(character)和字符串(string)? ==字符是一个信息单位。对使用字母系统或音节文字的自然语言,它大约对应为一个音位、类音位的单位或符号。简单来讲就是一个汉字、假名、数字、符号或一个西方语言的字母1 字符串是由零个或多个字符组成的有限序列==

[!NOTE] 什么是函数(function)? ==- 在计算机语境中,函数指的是一种子程序,它在可以实现固定运算功能的同时,还带有一个入口和一个出口,以sin(30)=0.5为例,这里括号内的30被称作函数的参数值,它将由入口——即函数包含的各个参数——传给计算机处理;在计算机求得值之后,由出口——即0.5,它被称作函数值——返回给调用这个函数的程序。 - 与数学语境中的函数不同的是,计算机语境中的函数可以根据其运算功能,由用户自行定义,只要运算功能固定,就可以被定义成一个函数,这样做可以避免相同的程序段在程序中重复出现,在需要时只要调用相应的函数就行了。如此一来,程序显得更为精简,可读性也更强。== ==由于数据库资料较少,计算机小白或可从 网络上的 Excel 资料入手,初步学习函数的应用==

==在正式开始探索可用数据库的预设函数之前,我们需要先了解一下 Obsidian 文档举例时,函数的各个字段都是什么意思,以file(path: string | file | url): file为例:==

  • ==path:表示参数内容,在这个例子中指的就是,在实际应用中不用写==
  • ==括号中的|表示并列关系,即“或”,这里表示函数支持字符串、文件、URL 三种参数类型,在实际应用中不用写==
  • ==()后紧接的:file仅示意返回的是文件对象,在实际应用中不用写==
  • ==有时括号中会出现?这表示这个参数是可选项,可写可不写==
  • ==函数可以彼此嵌套,例:file(link("[[filename]]"))==
  • ==在数据库工具栏的“筛选”或“属性”菜单中输入诸如date file等函数名,会出现下拉列表,点击即可自动补全函数,输入框上方也会提示函数写法==
  • 在编辑函数时,不同部分将由不同颜色进行区分,成对符号会在光标移至旁边时会突出显示,可避免漏写

用例图例

下文的代码示例中,会出现类似这样的表述:

  • aaa(bbb: ccc): ddd
  • 方法类eee.aaa():ddd

其解读如下:

  • aaa:函数(function)名
  • bbb:变量/参数名,一般是需要用户输入到函数中的值
  • ccc:变量/参数bbb的类型(type),如上文提到的字符串、数字、列表等,不一定只有一个
  • ddd:函数aaa执行后的输出值的类型
  • eee:类型为eee的一个变量

全局函数 (Global)

全局函数无需指定值的类型即可使用。

==escapeHTML()==

escapeHTML(html: string): string

- 将可能在 HTML 语言中有特殊含义的符号消义化,返回一个属性值类型为字符串的对象

date()

date(date: string): date

  • date(string): date解析提供的字符串,返回一个属性值类型为日期的对象
  • date函数中的字符串应采用YYYY-MM-DD HH:mm:ss格式,例:date("1871-03-28 12:00:00")返回的是代表1871年3月28日的日期对象

==duration()==

duration(value: string): duration

  • ==将字符串转换为一个时间段,字符串格式写法请见日期算术符==
  • 在执行日期算术时,时长无需显式解析(例: now() + '1d'),但如时长本身需要进行算术运算,则需要显式解析(例: now() + (duration('1d') * 2)
  • 当对时长与标量进行算术运算时,时长必须写在左边。例: duration('5h') * 2,而不是 2 * duration('5h')

file()

file(path: string | link | file ): file

  • 返回给定文件或路径的文件对象,这里的路径需要写成相对路径,在文件列表点击某笔记弹出的右键菜单中,点击“复制文件相对路径”即可复制
  • 例:file(link("[[filename]]"))file("path to file")

if()

if(condition: any, true_Result: any, false_Result?: any): any

  • condition 是需要评估的条件。
  • true_Result 是条件为真时输出的结果。
  • false_Result 是条件为假时的输出结果(可选)。如果未提供,则视为 null
  • 如果条件评估为真或是真值,则返回 true_Result,否则返回 false_Result
  • 例:if(isModified, "Modified", "Unmodified")

image()

image(path: string | file | link | url): image

  • 返回一个图像对象,该对象将在视图中渲染为图像。
  • 例:image(image-property)image("https://obsidian.md/images/obsidian-logo-gradient.svg")

icon()

icon(name: string): icon

  • 返回一个将在视图中渲染为图标的值。图标名称必须与 Lucide 图标匹配。
  • 例:icon("arrow-right")

link(path: string | file, display?: value): link

  • 函数在解析path字符串后会返回一个链接对象,该对象会渲染为指向给定路径的链接
  • 可选 display 参数来更改链接的锚文本

list()

list(element: any): list

  • 如果提供的元素是列表,则不加修改地返回它。
  • 否则,创建一个只包含单个元素的列表,将提供的 element 包裹在此列表中
  • 当仓库中的某属性的值既包含字符串,又包含列表时,此函数会很有用。
  • 例:list("value") 返回 ["value"]

max()

max(value1: number, value2: number...): number

  • 返回所有提供的数字中的最大值。

min()

min(value1: number, value2: number...): number

  • 返回所有提供的数字中的最小值。

now()

now(): date

  • now() 返回一个表示当前时间的日期对象。

number()

number(input: any): number

  • 函数会尝试将提供的参数值作为数字返回。
  • ==如果参数值类型为日期对象,返回自 Unix 时间戳以来的毫秒数==
  • 如果参数值类型为布尔值,返回 1 或 0
  • 如果参数值类型为字符串,它将被解析为数字返回,如果结果无效则返回错误
  • 例:number("3.4") 返回 3.4

today()

today(): date

  • today() 返回一个表示当前日期的日期对象,时间部分被设置为零

任意类型 (Any)

可用于属性值类型为任意类型的值的函数,包括字符串(例: "hello")、数字(例: 42)、列表(例: [1,2,3])或对象等。

isTruthy()

any.isTruthy(): boolean

  • 将任意值返回布尔值的==真==值。
  • 例:1.isTruthy() 返回 true

==isType()==

any.isType(type: string): boolean

  • ==如果跟在isType()字段前的属性值类型与括号内的预设类型一致,则返回真值==
  • ==例:"example".isType("string")true.isType("boolean")这两个函数都将返回真值==

toString()

any.toString(): string

  • 将任意类型的属性值返回为字符串表示形式
  • 例:123.toString() 返回 "123"

日期 (Date)

可用于处理属性值类型为日期和时间的函数,例如 date("2025-05-27")。日期比较可以使用日期算术来完成。

可用字段如下表所示:

字段类型含义
date.yearnumber日期的年份
date.monthnumber日期的月份 (1–12)
date.daynumber日期在月份中的天数
date.hournumber小时 (0–23)
date.minutenumber分钟 (0–59)
date.secondnumber秒 (0–59)
date.millisecondnumber毫秒 (0–999)

date()

date.date(): date

  • 返回一个移除了时间部分的日期对象。
  • 例:now().date().format("YYYY-MM-DD HH:mm:ss") 返回类似 字符串 “2025-12-31 00:00:00” 字符串

format()

date.format(format: string): string

  • ==括号中的参数值应填入格式化了的字符串,例:"YYYY-MM-DD"==
  • 返回按 Moment.js 字符串格式所指定的格式化后了的日期
  • 例:date.format("YYYY-MM-DD") 返回 "2025-05-27"

time()

date.time(): string

  • 返回时间
  • 例:now().time() 返回字符串”23:59:59”(此处具体时间根据实际情况变化)

relative()

date.relative(): string

  • 返回括号中填写的日期与当前日期的可读比较。
  • 例:file.mtime.relative() 返回类似 3 days ago 这样的值。

isEmpty()

date.isEmpty(): boolean

  • 返回 false。

字符串 (String)

可用于属性值类型为字符串(例如 "hello")的函数~~,在OB中使用时,需要将其包裹在英文双引号""中,否则将被视为属性名称。~~

可用字段如下表所示:

字段类型含义
string.lengthnumber字符串中的字符数

contains()

string.contains(value: string): boolean

  • 参数值代表要搜索的子字符串。
  • 如果目标字符串包含value,则返回真值true。
  • 例:"hello".contains("ell")返回真值true。

containsAll()

==string.containsAll(values: string): boolean==

  • 参数值代表一个或多个要搜索的子字符串
  • 如果目标字符串包含所有参数值,则返回真值true。
  • 例:"hello".containsAll("h", "e") 返回真值true

containsAny()

string.containsAny(...values: string): boolean

  • 参数值代表一个或多个要搜索的子字符串
  • 如果目标字符串至少包含一个参数值,则返回真值true。
  • 例:"hello".containsAny("x", "y", "e") 返回真值true

endsWith()

string.endsWith(query: string): boolean

  • 参数值代表要在目标字符串末尾检查的字符串
  • 如果目标字符串以query字符串结尾,则返回真值true。
  • 例:"hello".endsWith("lo")返回真值true。

isEmpty()

string.isEmpty(): boolean

  • 如果目标字符串不包含任何字符或==字符串根本不存在==,则返回==真值==。
  • 例:"".isEmpty() 返回 true
  • 例:"Hello world".isEmpty() 返回 false

lower()

string.lower(): string

  • 参数值返回转换为小写的字符串。

replace()

string.replace(pattern: string | Regexp, replacement: string): string

  • 前一个参数值pattern是要在目标字符串中搜索的值。
  • 后一个参数值replacement是用于替换搜索到的==前一个参数值,二者之间用英文逗号隔开==
  • 例子中的pattern分为属于字符串(string)或正则表达式(Regexp)两种情况:
    • 如果前一个参数值pattern是字符串,则所有出现的pattern都将被替换。
    • 如果前一个参数值pattern是正则表达式,==g标志意味着替换目标字符串中出现的所有“前一个参数值”==
  • 例:"a,b,c,d".replace(/,/, "-") 返回 "a-b,c,d",而 "a,b,c,d".replace(/,/g, "-") 返回 "a-b-c-d"

==repeat()==

==string.repeat(count: number): string==

==参数值count代表要重复字符串的次数== ==例:"123".repeat(2)返回"123123"==

reverse()

string.reverse(): string

  • 返回==字符变量string顺序倒转后==的字符串。
  • 例:"hello".reverse() 返回 "olleh"

slice()

string.slice(start: number, end?: number): string

  • ==前一个参数值start代表从该编码开始,提取该编码对应的字符及其后字符(何时结束见下文),第一个字符对应的编码是0而非1,其后字符的编码依此类推即可==
  • ==后一个参数值end可写可不写,代表本次字符提取在该编码对应的字符之前截止,不提取本编码对应的字符==
  • 返回从==前一个参数值start(含)到后一个参数值end==(不含)所对应的字符的子字符串。
  • 例:"hello".slice(1, 4)返回"ell"
  • ==如果输入时省略后一个参数end,则该函数将一直提取到字符串的结尾为止==

split()

string.split(separator: string | Regexp, n?: number): list

  • ==前一个参数值seperator==代表用于分割字符串的分隔符(可以为字符串string类型或正则表达式Regexp类型)。
  • ==后一个参数值n可写可不写,其代表函数返回的结果将包含前n个元素==
  • 返回子字符串组成的列表
  • 例:"a,b,c,d".split(",", 3)"a,b,c,d".split(/,/, 3) 返回 ["a", "b", "c"]

startsWith()

string.startsWith(query: string): boolean

  • 参数值query代表要在目标字符串开头检查的字符串
  • 如果此字符串以参数值query开头,则返回真值true。
  • 例:"hello".startsWith("he") 返回真值true。

title()

string.title(): string

  • 返回按照标题大小写语法转换后的字符串(每个单词的首字母大写)。
  • 例:"hello world".title() 返回 "Hello World"

trim()

string.trim(): string

  • 返回移除了两端空白字符的目标字符串
  • 例:" hi ".trim() 返回 "hi"

数字 (Number)

可用于属性值类型为数字(例如 423.14)的函数。

abs()

number.abs(): number

  • 返回目标数字的绝对值。
  • 例:(-5).abs() 返回 5

ceil()

number.ceil(): number

  • 将目标数字向上取整,返回大于或等于参数值,并与之最接近的整数
  • 例:(2.1).ceil() 返回 3

floor()

number.floor(): number

  • 将目标数字向下取整,返回小于或等于参数值,并与之最接近的整数
  • 例:(2.9).floor() 返回 2

isEmpty()

number.isEmpty(): boolean

  • 如果数字不存在,则返回 true。
  • 例:5.isEmpty()返回false

round()

number.round(digits?: number): number

  • 将目标数字四舍五入,返回与其最接近的整数。
  • digits为可选参数,如有,则digits参数值是多少,返回的数字就保留几位小数位数
  • 例:(2.5).round() 返回 3,而 (2.3333).round(2) 返回 2.33

toFixed()

number.toFixed(precision: number): string

  • 参数值代表是小数位数。
  • ~~precision~~参数值是多少,返回的字符串就保留多少位小数
  • 例:(3.14159).toFixed(2) 返回 "3.14"

列表 (List)

可用于属性值类型为有序元素列表(例: [1, 2, 3])的函数。

可用字段如下表所示:

字段类型描述
list.lengthnumber列表中的元素数量

contains()

list.contains(value: any): boolean

  • 参数值value代表要搜索的元素
  • 如果列表包含参数值value,则返回真值
  • 例:[1,2,3].contains(2)返回真值

containsAll()

list.containsAll(...values: any): boolean

  • 参数值value代表一个或多个要搜索的元素。
  • 如果列表包含所有参数值value,则返回真值
  • 例:[1,2,3].containsAll(2,3)返回真值

containsAny()

list.containsAny(...values: any): boolean

  • 参数值value代表一个或多个要搜索的元素。
  • 如果列表至少包含==参数值values其中的一个,则返回真值==
  • 例:[1,2,3].containsAny(3,4)返回真值

filter()

list.filter(value: Boolean): list

  • 通过调用一个筛选函数(这个筛选函数使用参数值valueindex这两个变量,返回布尔值,以决定是否应保留该元素)来筛选此列表的元素
    • 参数值value指的是列表中某个元素的值
    • index指的是现有值的索引
  • 例:[1,2,3,4].filter(value > 2)返回[3,4]

flat()

list.flat(): list

  • 将嵌套列表展平为单个列表。
  • 例:[1,[2,3]].flat()返回[1,2,3]

isEmpty()

list.isEmpty(): boolean

  • 如果列表没有元素,则返回真值
  • 例:[1,2,3].isEmpty() 返回假值

join()

list.join(separator: string): string

  • 参数值是要插入列表元素之间的字符串。
  • 将所有列表元素连接成一个单一的字符串。
  • 例:[1,2,3].join(",")返回"1,2,3"

map()

list.map(value: Any): list

  • 通过调用一个转换函数(这个转换函数使用参数值和index变量,返回要放入列表中的新值)来转换此列表的每个元素。
    • 参数值value指的是列表中某个元素的值
    • ==index指的是现有值的索引==
  • 例:[1,2,3,4].map(value + 1) 返回 [2,3,4,5]

reduce()

list.reduce(expression: Any, acc: Any): Any

  • 通过为列表中的每个元素运行一个表达式(该表达式可以使用变量 index 、 value 和 acc (累加器),并应返回下一个累加器值),将其元素归约为单个值。
    • expression 对列表中的每个元素进行评估。
    • value 是列表中当前项的值。
    • index 是当前项目的索引。
    • acc 是迄今为止的累计值。
  • 例(求和): [1,2,3].reduce(acc + value, 0) 返回 6 。
  • 例(最大值):values.filter(value.isType("number")).reduce(if(acc == null || value > acc, value, acc), null) 返回最大数值,若无则返回 null 。

reverse()

list.reverse(): list

  • 返回顺序反转后的列表。
  • 例:[1,2,3].reverse()返回[3,2,1]

slice()

list.slice(start: number, end?: number): list

  • ==前一个参数值start代表从该编码开始,提取该编码对应的字符及其后字符(何时结束见下文),第一个字符对应的编码是0而非1,其后字符的编码依此类推即可==
  • ==后一个参数值end可写可不写,代表本次字符提取在该编码对应的字符之前截止,不提取本编码对应的字符==
  • 返回从==前一个参数值start(含)到后一个参数值end==(不含)所对应的字符的子字符串。
  • 例:[1,2,3,4].slice(1,3)返回"[2,3]"
  • ==如果输入时省略后一个参数值end,则该函数将一直提取到列表的结尾为止==

sort()

list.sort(): list

  • 将列表元素从小到大排序。
  • 例:[3, 1, 2].sort()返回[1, 2, 3]
  • 例:["c", "a", "b"].sort()返回["a", "b", "c"]

unique()

list.unique(): list

  • 移除重复的列表元素。
  • 例:[1,2,2,3].unique()返回[1,2,3]

可用于属性值类型为链接的函数。通过函数可从文件(file.asLink())或路径(link("path")出发创建链接

asFile()

link.asFile(): file

  • 如果链接指向一个有效的本地文件,则返回一个文件对象。
  • 例:link("[[filename]]").asFile()

linksTo()

link.linksTo(file): boolean

  • 返回 link 指向的文件是否包含指向 file 的链接

文件 (File)

可用于 Obsidian 仓库中文件对象的函数。

可用字段如下表所示:

字段类型描述
file.namestring完整的文件名称
file.basenamestring不包含后缀名的文件名称
file.pathstring文件的相对路径
file.folderstring文件所在文件夹的相对路径
file.extstring文件的后缀名
file.sizenumber文件的大小,单位为字节
file.propertiesobject文件的笔记属性
file.tagslist文件包含的标签,包括行内标签
file.linkslist文件包含的内部链接
file.ctimedate文件的创建时间
file.mtimedate文件最后一次修改时间

file.asLink(display?: string): Link

  • ==display参数值可写可不写==,代表链接的锚文本/假名
  • 返回一个链接对象,该对象会渲染为一个可用的链接。
  • 例:file.asLink()

file.hasLink(otherFile: file | string): boolean

  • ==参数值otherFile代表==要检查的另一个文件或字符串路径。
  • 如果==文件file链接到参数值otherFile所指代的文件,则返回真值==
  • 例:如果存在从fileotherFile的链接,file.hasLink(otherFile) 返回真值

hasProperty()

file.hasProperty(name: string): boolean

  • 如果笔记具有==参数值name所指定的文件属性,则返回真值==

hasTag()

file.hasTag(...values: string): boolean

  • ==参数值values==是一个或多个标签名称。
  • 如果文件具有==参数值values中列出的任何一个标签,则返回 真值==
  • 例:如果文件包含“tag1”或“tag2”标签,包括#tag1/a#tag2/b这样的嵌套标签,则file.hasTag("tag1", "tag2")返回真值

inFolder()

file.inFolder(folder: string): boolean

  • ==参数值folder==是要检查的文件夹名称。
  • 如果文件位于==参数值folder所指定的文件夹中,则返回真值==
  • 例:file.inFolder("notes") 返回真值

对象 (Object)

可用于属性值类型为键值对集合(例如 {"a": 1, "b": 2})的函数。

其中,"a""b"是键,12分别是"a""b"两个键分别对应的值,"a": 1称为一个键值对,也叫一个项。

isEmpty()

object.isEmpty(): boolean

  • 如果对象自身不包含属性,则返回真值
  • 例:{}.isEmpty()返回真值

keys()

object.keys(): list

  • 返回一个包含对象所有键的列表。

values()

object.values(): list

  • 返回一个包含对象所有值的列表。

正则表达式 (Regular expression)

可用于正则表达式模式的函数。例:/abc/

matches()

regexp.matches(value: string): boolean

  • ==参数值value代表==要测试的字符串。
  • 如果正则表达式匹配参数值value,则返回真值true。
  • 例:/abc/.matches("abcde") 返回真值true。

Footnotes

  1. https://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)#:~:text=%E5%AD%97%E7%AC%A6%EF%BC%88character%EF%BC%89%E6%98%AF%E4%B8%80%E4%B8%AA%E4%BF%A1%E6%81%AF%E5%8D%95%E4%BD%8D%E3%80%82%E5%AF%B9%E4%BD%BF%E7%94%A8%E5%AD%97%E6%AF%8D%E7%B3%BB%E7%BB%9F%E6%88%96%E9%9F%B3%E8%8A%82%E6%96%87%E5%AD%97%E7%AD%89%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%EF%BC%8C%E5%AE%83%E5%A4%A7%E7%BA%A6%E5%AF%B9%E5%BA%94%E4%B8%BA%E4%B8%80%E4%B8%AA%E9%9F%B3%E4%BD%8D%E3%80%81%E7%B1%BB%E9%9F%B3%E4%BD%8D%E7%9A%84%E5%8D%95%E4%BD%8D%E6%88%96%E7%AC%A6%E5%8F%B7%E3%80%82%E7%AE%80%E5%8D%95%E6%9D%A5%E8%AE%B2%E5%B0%B1%E6%98%AF%E4%B8%80%E4%B8%AA%E6%B1%89%E5%AD%97%E3%80%81%E5%81%87%E5%90%8D%E3%80%81%E9%9F%A9%E6%96%87%E5%AD%97%E2%80%A6%E2%80%A6%EF%BC%8C%E6%88%96%E6%98%AF%E4%B8%80%E4%B8%AA%E8%8B%B1%E6%96%87%E3%80%81%E5%85%B6%E4%BB%96%E8%A5%BF%E6%96%B9%E8%AF%AD%E8%A8%80%E7%9A%84%E5%AD%97%E6%AF%8D%E3%80%82

讨论

若阁下有独到的见解或新颖的想法,诚邀您在文章下方留言,与大家共同探讨。



反馈交流

其他渠道

版权声明
pkmer forum 论坛相关