Functions
Dataview functions provide more advanced ways to manipulate data. You can use functions in data commands (except FROM) to filter or group or use them as additional information like TABLE columns or extra output for LIST queries to see your data in a new light.
How functions work
Functions are another form of expression and can be used everywhere you can use an expression. A function always gives you back a new value and follows this format:
functionname(parameter1, parameter2)
Parameters are again expressions and you can use literals, meta data fields, or even another function as parameter. You'll find out which data type your parameters need to have on the documentation of this page. Pay attention to the information inside the function brackets. Parameters in square brackets, i.e. link(path, [display])
means they are optional and can be omitted. Find out more about the default behaviour of each function on their explanation.
Calling functions on lists of values
Most functions can be applied either to single values (like number
, string
, date
, etc.) OR to lists of those
values. If a function is applied to a list, it also returns a list after the function is applied to each element
in the list. For example:
lower("YES") = "yes"
lower(["YES", "NO"]) = ["yes", "no"]
replace("yes", "e", "a") = "yas"
replace(["yes", "ree"], "e", "a") = ["yas", "raa"]
This so-called "function vectorization" will not be mentioned explicitly on the following definitions and is possible for a wide range of these functionalities implicitly.
Constructors
Constructors which create values.
object(key1, value1, ...)
Creates a new object with the given keys and values. Keys and values should alternate in the call, and keys should always be strings/text.
object() => empty object
object("a", 6) => object which maps "a" to 6
object("a", 4, "c", "yes") => object which maps a to 4, and c to "yes"
list(value1, value2, ...)
Creates a new list with the given values in it. array
can be used an alias for list
.
list() => empty list
list(1, 2, 3) => list with 1, 2, and 3
array("a", "b", "c") => list with "a", "b", and "c"
date(any)
Parses a date from the provided string, date, or link object, if possible, returning null otherwise.
date("2020-04-18") = <date object representing April 18th, 2020>
date([[2021-04-16]]) = <date object for the given page, referring to file.day>
date(text, format)
Parses a date from text to luxon DateTime
with the specified format. Note localised formats might not work.
Uses Luxon tokens.
date("12/31/2022", "MM/dd/yyyy") => DateTime for Decemeber 31th, 2022
date("210313", "yyMMdd") => DateTime for March 13th, 2021
date("946778645000", "x") => DateTime for "2000-01-02T03:04:05"
dur(any)
Parses a duration from the provided string or duration, returning null on failure.
dur(8 minutes) = <8 minutes>
dur("8 minutes, 4 seconds") = <8 minutes, 4 seconds>
dur(dur(8 minutes)) = dur(8 minutes) = <8 minutes>
number(string)
Pulls the first number out of the given string, returning it if possible. Returns null if there are no numbers in the string.
number("18 years") = 18
number(34) = 34
number("hmm") = null
string(any)
Converts any value into a "reasonable" string representation. This sometimes produces less pretty results than just directly using the value in a query - it is mostly useful for coercing dates, durations, numbers, and so on into strings for manipulation.
string(18) = "18"
string(dur(8 hours)) = "8 hours"
string(date(2021-08-15)) = "August 15th, 2021"
link(path, [display])
Construct a link object from the given file path or name. If provided with two arguments, the second argument is the display name for the link.
link("Hello") => link to page named 'Hello'
link("Hello", "Goodbye") => link to page named 'Hello', displays as 'Goodbye'
embed(link, [embed?])
Convert a link object into an embedded link; support for embedded links is somewhat spotty in Dataview views, though embedding of images should work.
embed(link("Hello.png")) => embedded link to the "Hello.png" image, which will render as an actual image.
elink(url, [display])
Construct a link to an external url (like www.google.com
). If provided with two arguments, the second
argument is the display name for the link.
elink("www.google.com") => link element to google.com
elink("www.google.com", "Google") => link element to google.com, displays as "Google"
typeof(any)
Get the type of any object for inspection. Can be used in conjunction with other operators to change behavior based on type.
typeof(8) => "number"
typeof("text") => "string"
typeof([1, 2, 3]) => "array"
typeof({ a: 1, b: 2 }) => "object"
typeof(date(2020-01-01)) => "date"
typeof(dur(8 minutes)) => "duration"
Numeric Operations
round(number, [digits])
Round a number to a given number of digits. If the second argument is not specified, rounds to the nearest whole number; otherwise, rounds to the given number of digits.
round(16.555555) = 17
round(16.555555, 2) = 16.56
trunc(number)
Truncates ("cuts off") the decimal point from a number.
trunc(12.937) = 12
trunc(-93.33333) = -93
trunc(-0.837764) = 0
floor(number)
Always rounds down and returns the largest integer less than or equal to a given number. This means that negative numbers become more negative.
floor(12.937) = 12
floor(-93.33333) = -94
floor(-0.837764) = -1
ceil(number)
Always rounds up and returns the smallest integer greater than or equal to a given number. This means negative numbers become less negative.
ceil(12.937) = 13
ceil(-93.33333) = -93
ceil(-0.837764) = 0
min(a, b, ..)
Compute the minimum value of a list of arguments, or an array.
min(1, 2, 3) = 1
min([1, 2, 3]) = 1
min("a", "ab", "abc") = "a"
max(a, b, ...)
Compute the maximum value of a list of arguments, or an array.
max(1, 2, 3) = 3
max([1, 2, 3]) = 3
max("a", "ab", "abc") = "abc"
sum(array)
Sums all numeric values in the array. If you have null values in your sum, you can eliminate them via the nonnull
function.
sum([1, 2, 3]) = 6
sum([]) = null
sum(nonnull([null, 1, 8])) = 9
product(array)
Calculates the product of a list of numbers. If you have null values in your average, you can eliminate them via the nonnull
function.
product([1,2,3]) = 6
product([]) = null
product(nonnull([null, 1, 2, 4])) = 8
reduce(array, operand)
A generic function to reduce a list into a single value, valid operands are "+"
, "-"
, "*"
, "/"
and the boolean operands "&"
and "|"
. Note that using "+"
and "*"
equals the sum()
and product()
functions, and using "&"
and "|"
matches all()
and any()
.
reduce([100, 20, 3], "-") = 77
reduce([200, 10, 2], "/") = 10
reduce(values, "*") = Multiplies every element of values, same as product(values)
reduce(values, this.operand) = Applies the local field operand to each of the values
reduce(["⭐", 3], "*") = "⭐⭐⭐", same as "⭐" * 3
reduce([1]), "+") = 1, has the side effect of reducing the list into a single element
average(array)
Computes the numeric average of numeric values. If you have null values in your average, you can eliminate them via the
nonnull
function.
average([1, 2, 3]) = 2
average([]) = null
average(nonnull([null, 1, 2])) = 1.5
minby(array, function)
Compute the minimum value of an array, using the provided function.
minby([1, 2, 3], (k) => k) = 1
minby([1, 2, 3], (k) => 0 - k) => 3
minby(this.file.tasks, (k) => k.due) => (earliest due)
maxby(array, function)
Compute the maximum value of an array, using the provided function.
maxby([1, 2, 3], (k) => k) = 3
maxby([1, 2, 3], (k) => 0 - k) => 1
maxby(this.file.tasks, (k) => k.due) => (latest due)
--
Objects, Arrays, and String Operations
Operations that manipulate values inside of container objects.
contains()
and friends
For a quick summary, here are some examples:
contains("Hello", "Lo") = false
contains("Hello", "lo") = true
icontains("Hello", "Lo") = true
icontains("Hello", "lo") = true
econtains("Hello", "Lo") = false
econtains("Hello", "lo") = true
econtains(["this","is","example"], "ex") = false
econtains(["this","is","example"], "is") = true
contains(object|list|string, value)
Checks if the given container type has the given value in it. This function behave slightly differently based on whether the first argument is an object, a list, or a string. This function is case-sensitive.
- For objects, checks if the object has a key with the given name. For example,
contains(file, "ctime") = true contains(file, "day") = true (if file has a date in its title, false otherwise)
- For lists, checks if any of the array elements equals the given value. For example,
contains(list(1, 2, 3), 3) = true contains(list(), 1) = false
- For strings, checks if the given value is a substring (i.e., inside) the string.
contains("hello", "lo") = true contains("yes", "no") = false
icontains(object|list|string, value)
Case insensitive version of contains()
.
econtains(object|list|string, value)
"Exact contains" checks if the exact match is found in the string/list. This function is case sensitive.
-
For strings, it behaves exactly like
contains()
.econtains("Hello", "Lo") = false econtains("Hello", "lo") = true
-
For lists, it checks if the exact word is in the list.
econtains(["These", "are", "words"], "word") = false econtains(["These", "are", "words"], "words") = true
-
For objects, it checks if the exact key name is present in the object. It does not do recursive checks.
econtains({key:"value", pairs:"here"}, "here") = false econtains({key:"value", pairs:"here"}, "key") = true econtains({key:"value", recur:{recurkey: "val"}}, "value") = false econtains({key:"value", recur:{recurkey: "val"}}, "Recur") = false econtains({key:"value", recur:{recurkey: "val"}}, "recurkey") = false
containsword(list|string, value)
Checks if value
has an exact word match in string
or list
.
This is case insensitive.
The outputs are different for different types of input, see examples.
-
For strings, it checks if the word is present in the given string.
containsword("word", "word") = true containsword("word", "Word") = true containsword("words", "Word") = false containsword("Hello there!", "hello") = true containsword("Hello there!", "HeLLo") = true containsword("Hello there chaps!", "chap") = false containsword("Hello there chaps!", "chaps") = true
-
For lists, it returns a list of booleans indicating if the word's exact case insensitive match was found.
containsword(["I have no words.", "words"], "Word") = [false, false] containsword(["word", "Words"], "Word") = [true, false] containsword(["Word", "Words in word"], "WORD") = [true, true]
extract(object, key1, key2, ...)
Pulls multiple fields out of an object, creating a new object with just those fields.
extract(file, "ctime", "mtime") = object("ctime", file.ctime, "mtime", file.mtime)
extract(object("test", 1)) = object()
sort(list)
Sorts a list, returning a new list in sorted order.
sort(list(3, 2, 1)) = list(1, 2, 3)
sort(list("a", "b", "aa")) = list("a", "aa", "b")
reverse(list)
Reverses a list, returning a new list in reversed order.
reverse(list(1, 2, 3)) = list(3, 2, 1)
reverse(list("a", "b", "c")) = list("c", "b", "a")
length(object|array)
Returns the number of fields in an object, or the number of entries in an array.
length([]) = 0
length([1, 2, 3]) = 3
length(object("hello", 1, "goodbye", 2)) = 2
nonnull(array)
Return a new array with all null values removed.
nonnull([]) = []
nonnull([null, false]) = [false]
nonnull([1, 2, 3]) = [1, 2, 3]
all(array)
Returns true
only if ALL values in the array are truthy. You can also pass multiple arguments to this function, in
which case it returns true
only if all arguments are truthy.
all([1, 2, 3]) = true
all([true, false]) = false
all(true, false) = false
all(true, true, true) = true
You can pass a function as second argument to return only true if all elements in the array matches the predicate.
all([1, 2, 3], (x) => x > 0) = true
all([1, 2, 3], (x) => x > 1) = false
all(["apple", "pie", 3], (x) => typeof(x) = "string") = false
any(array)
Returns true
if ANY of the values in the array are truthy. You can also pass multiple arguments to this function, in
which case it returns true
if any of the arguments are truthy.
any(list(1, 2, 3)) = true
any(list(true, false)) = true
any(list(false, false, false)) = false
any(true, false) = true
any(false, false) = false
You can pass a function as second argument to return only true if any element in the array matches the predicate.
any(list(1, 2, 3), (x) => x > 2) = true
any(list(1, 2, 3), (x) => x = 0) = false
none(array)
Returns true
if NONE of the values in the array are truthy.
none([]) = true
none([false, false]) = true
none([false, true]) = false
none([1, 2, 3]) = false
You can pass a function as second argument to return only true if none of the elements in the array matches the predicate.
none([1, 2, 3], (x) => x = 0) = true
none([true, true], (x) => x = false) = true
none(["Apple", "Pi", "Banana"], (x) => startswith(x, "A")) = false
join(array, [delimiter])
Joins elements in an array into a single string (i.e., rendering them all on the same line). If provided with a second argument, then each element will be separated by the given separator.
join(list(1, 2, 3)) = "1, 2, 3"
join(list(1, 2, 3), " ") = "1 2 3"
join(6) = "6"
join(list()) = ""
filter(array, predicate)
Filters elements in an array according to the predicate, returning a new list of the elements which matched.
filter([1, 2, 3], (x) => x >= 2) = [2, 3]
filter(["yes", "no", "yas"], (x) => startswith(x, "y")) = ["yes", "yas"]
map(array, func)
Applies the function to each element in the array, returning a list of the mapped results.
map([1, 2, 3], (x) => x + 2) = [3, 4, 5]
map(["yes", "no"], (x) => x + "?") = ["yes?", "no?"]
flat(array, [depth])
Concatenates sub-levels of the array to the desired depth. Default is 1 level, but it can
concatenate multiple levels. E.g. Can be used to reduce array depth on rows
lists after
doing GROUP BY
.
flat(list(1, 2, 3, list(4, 5), 6)) => list(1, 2, 3, 4, 5, 6)
flat(list(1, list(21, 22), list(list (311, 312, 313))), 4) => list(1, 21, 22, 311, 312, 313)
flat(rows.file.outlinks)) => All the file outlinks at first level in output
slice(array, [start, [end]])
Returns a shallow copy of a portion of an array into a new array object selected from start
to end
(end
not included) where start
and end
represents the index of items in that array.
slice([1, 2, 3, 4, 5], 3) = [4, 5] => All items from given position, 0 as first
slice(["ant", "bison", "camel", "duck", "elephant"], 0, 2) = ["ant", "bison"] => First two items
slice([1, 2, 3, 4, 5], -2) = [4, 5] => counts from the end, last two items
slice(someArray) => a copy of someArray
String Operations
regextest(pattern, string)
Checks if the given regex pattern can be found in the string (using the JavaScript regex engine).
regextest("\w+", "hello") = true
regextest(".", "a") = true
regextest("yes|no", "maybe") = false
regextest("what", "what's up dog?") = true
regexmatch(pattern, string)
Checks if the given regex pattern matches the entire string, using the JavaScript regex engine.
This differs from regextest
in that regextest can match just parts of the text.
regexmatch("\w+", "hello") = true
regexmatch(".", "a") = true
regexmatch("yes|no", "maybe") = false
regexmatch("what", "what's up dog?") = false
regexreplace(string, pattern, replacement)
Replaces all instances where the regex pattern
matches in string
, with replacement
. This uses the JavaScript
replace method under the hood, so you can use special characters like $1
to refer to the first capture group, and so on.
regexreplace("yes", "[ys]", "a") = "aea"
regexreplace("Suite 1000", "\d+", "-") = "Suite -"
replace(string, pattern, replacement)
Replace all instances of pattern
in string
with replacement
.
replace("what", "wh", "h") = "hat"
replace("The big dog chased the big cat.", "big", "small") = "The small dog chased the small cat."
replace("test", "test", "no") = "no"
lower(string)
Convert a string to all lower case.
lower("Test") = "test"
lower("TEST") = "test"
upper(string)
Convert a string to all upper case.
upper("Test") = "TEST"
upper("test") = "TEST"
split(string, delimiter, [limit])
Split a string on the given delimiter string. If a third argument is provided, it limits the number of splits that occur. The delimiter string is interpreted as a regular expression. If there are capture groups in the delimiter, matches are spliced into the result array, and non-matching captures are empty strings.
split("hello world", " ") = list("hello", "world")
split("hello world", "\s") = list("hello", "world")
split("hello there world", " ", 2) = list("hello", "there")
split("hello there world", "(t?here)") = list("hello ", "there", " world")
split("hello there world", "( )(x)?") = list("hello", " ", "", "there", " ", "", "world")
startswith(string, prefix)
Checks if a string starts with the given prefix.
startswith("yes", "ye") = true
startswith("path/to/something", "path/") = true
startswith("yes", "no") = false
endswith(string, suffix)
Checks if a string ends with the given suffix.
endswith("yes", "es") = true
endswith("path/to/something", "something") = true
endswith("yes", "ye") = false
padleft(string, length, [padding])
Pads a string up to the desired length by adding padding on the left side. If you omit the padding character, spaces will be used by default.
padleft("hello", 7) = " hello"
padleft("yes", 5, "!") = "!!yes"
padright(string, length, [padding])
Equivalent to padleft
, but pads to the right instead.
padright("hello", 7) = "hello "
padright("yes", 5, "!") = "yes!!"
substring(string, start, [end])
Take a slice of a string, starting at start
and ending at end
(or the end of the string if unspecified).
substring("hello", 0, 2) = "he"
substring("hello", 2, 4) = "ll"
substring("hello", 2) = "llo"
substring("hello", 0) = "hello"
truncate(string, length, [suffix])
Truncate a string to be at most the given length, including the suffix
(which defaults to ...
). Generally useful
to cut off long text in tables.
truncate("Hello there!", 8) = "Hello..."
truncate("Hello there!", 8, "/") = "Hello t/"
truncate("Hello there!", 10) = "Hello t..."
truncate("Hello there!", 10, "!") = "Hello the!"
truncate("Hello there!", 20) = "Hello there!"
Utility Functions
default(field, value)
If field
is null, return value
; otherwise return field
. Useful for replacing null values with defaults. For example, to show projects which haven't been completed yet, use "incomplete"
as their default value:
default(dateCompleted, "incomplete")
Default is vectorized in both arguments; if you need to use default explicitly on a list argument, use ldefault
, which
is the same as default but is not vectorized.
default(list(1, 2, null), 3) = list(1, 2, 3)
ldefault(list(1, 2, null), 3) = list(1, 2, null)
choice(bool, left, right)
A primitive if statement - if the first argument is truthy, returns left; otherwise, returns right.
choice(true, "yes", "no") = "yes"
choice(false, "yes", "no") = "no"
choice(x > 4, y, z) = y if x > 4, else z
hash(seed, [text], [variant])
Generate a hash based on the seed
, and the optional extra text
or a variant number
. The function
generates a fixed number based on the combination of these parameters, which can be used to randomise
the sort order of files or lists/tasks. If you choose a seed
based on a date, i.e. "2024-03-17",
or another timestamp, i.e. "2024-03-17 19:13", you can make the "randomness" be fixed
related to that timestamp. variant
is a number, which in some cases is needed to make the combination of
text
and variant
become unique.
hash(dateformat(date(today), "YYYY-MM-DD"), file.name) = ... A unique value for a given date in time
hash(dateformat(date(today), "YYYY-MM-DD"), file.name, position.start.line) = ... A unique "random" value in a TASK query
This function can be used in a SORT
statement to randomise the order. If you're using a TASK
query,
since the file name could be the same for multiple tasks, you can add some number like the starting line
number (as shown above) to make it a unique combination. If using something like FLATTEN file.lists as item
,
the similar addition would be to do item.position.start.line
as the last parameter.
striptime(date)
Strip the time component of a date, leaving only the year, month, and day. Good for date comparisons if you don't care about the time.
striptime(file.ctime) = file.cday
striptime(file.mtime) = file.mday
dateformat(date|datetime, string)
Format a Dataview date using a formatting string. Uses Luxon tokens.
dateformat(file.ctime,"yyyy-MM-dd") = "2022-01-05"
dateformat(file.ctime,"HH:mm:ss") = "12:18:04"
dateformat(date(now),"x") = "1407287224054"
dateformat(file.mtime,"ffff") = "Wednesday, August 6, 2014, 1:07 PM Eastern Daylight Time"
Note: dateformat()
returns a string, not a date, so you can't compare it against the result from a call to date()
or a variable like file.day
which already is a date. To make those comparisons you can format both arguments.
durationformat(duration, string)
Format a Dataview duration using a formatting string. Anything inside single quotes will not be treated as a token and instead will be shown in the output as written. See examples.
You may use these tokens:
S
for millisecondss
for secondsm
for minutesh
for hoursd
for daysw
for weeksM
for monthsy
for years
durationformat(dur("3 days 7 hours 43 seconds"), "ddd'd' hh'h' ss's'") = "003d 07h 43s"
durationformat(dur("365 days 5 hours 49 minutes"), "yyyy ddd hh mm ss") = "0001 000 05 49 00"
durationformat(dur("2000 years"), "M months") = "24000 months"
durationformat(dur("14d"), "s 'seconds'") = "1209600 seconds"
currencyformat(number, [currency])
Presents the number depending on your current locale, according to the currency
code, from ISO 4217.
number = 123456.789
currencyformat(number, "EUR") = €123,456.79 in locale: en_US)
currencyformat(number, "EUR") = 123.456,79 € in locale: de_DE)
currencyformat(number, "EUR") = € 123 456,79 in locale: nb)
localtime(date)
Converts a date in a fixed timezone to a date in the current timezone.
meta(link)
Get an object containing metadata of a link. When you access a property on a link what you get back is the property
value from the linked file. The meta
function makes it possible to access properties of the link itself.
There are several properties on the object returned by meta
:
meta(link).display
Get the display text of a link, or null if the link does not have defined display text.
meta([[2021-11-01|Displayed link text]]).display = "Displayed link text"
meta([[2021-11-01]]).display = null
meta(link).embed
True or false depending on whether the link is an embed. Those are links that begin with an exclamation mark, like
![[Some Link]]
.
meta(link).path
Get the path portion of a link.
meta([[My Project]]).path = "My Project"
meta([[My Project#Next Actions]]).path = "My Project"
meta([[My Project#^9bcbe8]]).path = "My Project"
meta(link).subpath
Get the subpath of a link. For links to a heading within a file the subpath will be the text of the heading. For links to a block the subpath will be the block ID. If neither of those cases applies then the subpath will be null.
meta([[My Project#Next Actions]]).subpath = "Next Actions"
meta([[My Project#^9bcbe8]]).subpath = "9bcbe8"
meta([[My Project]]).subpath = null
This can be used to select tasks under specific headings.
```dataview
task
where meta(section).subpath = "Next Actions"
```
meta(link).type
Has the value "file", "header", or "block" depending on whether the link links to an entire file, a heading within a file, or to a block within a file.
meta([[My Project]]).type = "file"
meta([[My Project#Next Actions]]).type = "header"
meta([[My Project#^9bcbe8]]).type = "block"