List
List
概述
列表是一种有序结构。
排序
默认的可排序类型必须是Number
、Date
、Time
、DateTime
、DateTimeZone
、Duration
、Text
、Logical
、Null
。
类型
列表在语义上是存在类型的,但是它的类型并不是强绑定的,而是期望类型。
列表不同于数组(M中不存在数组,只是举例),数组要求类型一致,但列表不需要,仅在某些具体情况下才会要求列表中每个值的类型一致。但类型不同可能会导致在计算中需要做更多的判断,因此,列表中项的类型通常都是一样的。
对于某些计算需要类型本身支持某种运算才可以使用,比如:
List.Sum
:需要类型支持相同类型相加。List.Product
:需要类型支持相同类型相乘。List.Average
:需要类型支持与number
的除法。
延迟计算和流式计算
对于列表而言,因为延迟计算、流式语义等原因,会出现一些特殊的现象:
List.Count
:仅统计个数,不对项求值。List.Contains
:存在类似逻辑运算的短路机制,一旦能够确定结果就会中止计算并返回结果。
但是,如果计算中途遇到错误,这个错误可能当前步骤不会出现问题,但会影响其它计算,参见下一小节:错误。
流式语义的初衷是降低计算量,但是也可能会产生一些隐患。
错误
某些函数遇到错误会中止计算,并且有可能保留一部分结果,这部分结果可能会影响下一步的计算。
List.Count({1, 2, error "a"})
:3
List.Count(List.Distinct({0, 1, 1, error "a", 4}))
:error "a"
函数作为参数
M语言中的函数由很多需要使用函数作为参数,为了简化描述,下文称之为“参数函数”。在函数执行过程中,参数函数会被隐式的传参调用,有可能是一个参数或多个参数。但是不管怎样,通常M都是按照函数的参数顺序对参数函数进行传参的。因此,一般情况下,通过观察函数的参数可以就可以猜测出需要何种类型的函数。
对于某些函数还存在一些复杂的情况,如List.Sort
,它支持一个参数的函数、两个参数的函数、函数列表、函数加排序方式的列表四种情况。另外,也支持官方给出的一些函数,但是都属于上面的一种。
构造语法
使用成对的{
和}
中间使用,
间隔构造列表。
列表中每个项的类型通常都是相同的,但你可以设置为不同。
{1, 2, 3, 4}
{1, "A", (x) => x + 1, #time(0, 0, 0)}
对于某些连续值可以使用..
创建,支持number
类型和单个字符的text
类型。
如果是text
类型的值使用该语法,则根据Unicode编码进行创建。
// 1 - 5
{1..5}
// A ~ F
{"A".."F"}
// \u6211 ~ \u6215
{"我".."戕"}
List.Accumulate
List.Accumulate(
list as list,
seed as any,
accumulator as function
) as any
遍历列表list
并使用函数accumulator
计算得出结果,可以指定初始值seed
。
函数accumulator
必须拥有两个参数,第一个参数对应当前seed
的值,第二参数对应list
的每个项。这种隐式传参的方式在很多以函数为参数的函数中非常常见。
执行方式:
- 初始化
seed
。 - 循环体,按照
list
的顺序执行。- 判定循环体是否结束,即列表
list
中的项是否完全取出。如果结束,返回seed
当前的值;否则继续向下执行。 - 按照顺序取出
list
中的某个值i
。 - 将
seed
和i
带入accumulator
,产生的结果赋予seed
。
- 判定循环体是否结束,即列表
- 返回当前
seed
的值。
示例:
// 理解循环终止并取出seed
List.Accumulate({}, 666, (s, v) => v + s)
List.Accumulate({}, 666, (s, v) => v)
List.Accumulate({}, 666, (s, v) => s)
// 1-9拼接为数字123456789
List.Accumulate({1..9}, 0, (s, v) => s * 10 + v)
// 1-9偶数求和
List.Accumulate({1..9}, 0, (s, v) => s + (if Number.Mod(v, 2) = 0 then v else 0))
List.Accumulate({1..9}, 0, (s, v) => s + (1 - Number.Mod(v, 2)) * v)
// 1-9奇数求和
List.Accumulate({1..9}, 0, (s, v) => s + (if Number.Mod(v, 2) <> 0 then v else 0))
List.Accumulate({1..9}, 0, (s, v) => s + Number.Mod(v, 2) * v)
// 保留奇数的内容
List.Accumulate({1..9}, {}, (s, v) => if Number.Mod(v, 2) <> 0 then s & {v} else s)
List.AllTrue
List.AllTrue(list as list) as logical
当列表list
中的值均为true
时返回true
。该函数会忽略null
。
注意
该函数会对列表中所有项进行求值,因此,如果存在错误会中断计算。
// true
List.AllTrue({null, true})
List.Alternate
List.Alternate(
list as list,
count as number,
optional repeatInterval as nullable number,
optional offset as nullable number
) as list
对列表的项序号进行跳过和选择,得到部分内容。
count
:跳过的项个数。repeatInterval
:连续选择的项个数。默认选择跳过count
个项之后的所有项。offset
:从开头第几个项开始跳过,或者说先选择前几个项。默认为0,即开头不选择。
执行步骤:
- 选择
offset
个项,如果未指定或指定为0
,则此处不选择。 - 循环步骤:
- 跳过
count
个项 - 选择
repeatInterval
个项
- 跳过
- 最终输出
offset
与repeatInterval
选择的项。
示例:
// {2..9}
List.Alternate({1..9}, 1)
// {2, 3, 5, 6, 8, 9}
List.Alternate({1..9}, 1, 2)
// {2, 3, 4, 5, 7, 8, 9}
List.Alternate({1..9}, 1, 4)
// {1, 2, 3, 5, 6, 7, 8}
List.Alternate({1..9}, 1, 4, 3)
List.AnyTrue
List.AnyTrue(list as list) as logical
列表任意项为true
则返回true
。忽略null
。
注意
该函数会对列表中所有项进行求值,因此,如果存在错误会中断计算。
List.AnyTrue({null, true})
List.AnyTrue({null, 1 > 2})
List.Average
List.Average(list as list, optional precision as nullable number) as any
求数组项的均值。忽略null
。
如果列表没有项或者都是null
,将会返回null
。
仅支持处理number
、date
、time
、datetime
、datetimezone
和duration
类型的值,且必须是同一类型。
对于date
类型需要额外小心,因为可能会对日期均值取整。
// null
List.Average({null})
// 1.5
List.Average({null, 1, 2})
// 2022/1/1
List.Average({null, #date(2022, 1, 1), #date(2022, 1, 2)})
precision
参数用于指定计算精度,可以使用Precision.Type枚举值或数字:
Precision.Double
:默认值。浮点精度。Precision.Decimal
:十进制精度。
// 0.15000000000000002
List.Average({0.1, 0.2})
// 0.15
List.Average({0.1, 0.2}, Precision.Decimal)
List.Buffer
List.Buffer(list as list) as list
在内存中缓存列表list
。
该函数的结果是稳定的列表,即会立即对列表进行完整的计算,不再考虑流式语义。
因为M引擎本身的限制,如果内存无法容纳完整的list
,结果可能会被分页到磁盘中。因此,该函数不一定能够加快代码的执行,甚至有可能降低。
List.Combine
List.Combine(lists as list) as list
合并列表list
中的列表为一个新的列表。
该函数只能合并一层,并不会读取全部层级。
// {1, 2, 3, {4}}
List.Combine({{1, 2}, {3, {4}}})
List.ConformToPageReader
List.ConformToPageReader(list as list, optional options as nullable record) as table
内部函数。
List.Contains
List.Contains(list as list, value as any, optional equationCriteria as any) as logical
查找列表list
中是否包含值value
,如果包含则返回true
。可以使用函数equationCriteria
来自定义比较方式。
如果没有对equationCriteria
传参,将使用Value.Equals
。
equationCriteria
是一个需要两个参数的函数,函数原型(listItem as any, value as any) as logical
,第一个参数表示数组list
的每一个项,第二个参数表示value
。
注意
该函数一旦在列表list
中找到value
就会立即中止执行并返回true
,不一定会完全遍历完列表list
,除非全部为false
。
当列表中存在错误时且查找值在错误之前时,不会引发错误(因为会立即返回true
),否则会引发错误而终止计算。
// error "a"
List.Contains({1, error "a", 3}, 3)
// true
List.Contains({1, error "a", 3}, 1)
// 是否包含“3的倍数”
List.Contains({1..3}, 3, (x, y) => Number.Mod(x, y) = 0)
List.Contains({1..3}, null, (x, y) => Number.Mod(x, 3) = 0)
List.ContainsAll
List.ContainsAll(
list as list,
values as list,
optional equationCriteria as any
) as logical
列表list
包含列表values
中的全部项时返回true
。
如果没有对equationCriteria
传参,将使用Value.Equals
。
equationCriteria
是一个需要两个参数的函数,函数原型(listItem as any, valuesItem as any) as logical
,第一个参数表示数组list
的每一个项,第二个参数表示values
中的每一个项。
注意
一旦values
中的所有项都被检查到存在,函数就会中止检查并立即返回true
。因此,函数可能不会完全检查列表list
。
当列表中存在错误时且查找值在错误之前时,不会引发错误(因为会立即返回true
),否则会引发错误而终止计算。
// true
List.ContainsAll({1, 2, error "a", 4, 5}, {1, 2})
// error "a"
List.ContainsAll({1, 2, error "a", 4, 5}, {1, 3})
// true
List.ContainsAll({1, 4, 5, 7, 8, 9}, {1, 2}, (x, y) => x = y * 3 + 2)
// false
List.ContainsAll({1, 4, 5, 7, 9}, {1, 2}, (x, y) => x = y * 3 + 2)
List.ContainsAny
List.ContainsAny(
list as list,
values as list,
optional equationCriteria as any
) as logical
列表list
包含列表values
中的任意项时返回true
。
如果没有对equationCriteria
传参,将使用Value.Equals
。
equationCriteria
是一个需要两个参数的函数,函数原型(listItem as any, valuesItem as any) as logical
,第一个参数表示数组list
的每一个项,第二个参数表示values
中的每一个项。
注意
一旦values
中的任意项被检查到存在,函数就会中止检查并立即返回true
。因此,函数可能不会完全检查列表list
。
当列表中存在错误时且查找值在错误之前时,不会引发错误(因为会立即返回true
),否则会引发错误而终止计算。
// true
List.ContainsAny({1, error "a", 5, 7, 9}, {1, 2})
// true
List.ContainsAny({1, 4, 5, 7, 9}, {1, 2}, (x, y) => x = y * 3 + 2)
List.Count
List.Count(list as list) as number
返回列表中的项个数。
该函数仅统计当前层级并且不会对项进行求值。
List.Count({error "a"})
相关信息
已知问题:该函数可以在Table.Group
函数中对分组表进行行计数,原因未知。
Table.Group(
#table({"A"}, {{1}, {1}, {2}, {3}}),
"A",
{
{"List.Count", List.Count},
{"Is List", each _ is list},
{"Is Table", each _ is table}
}
)
List.Covariance
List.Covariance(numberList1 as list, numberList2 as list) as nullable number
返回两个列表之间的协方差。
两个列表必须拥有相同的项数。
List.Dates
List.Dates(start as date, count as number, step as duration) as list
从日期start
开始,按照步长step
最终生成count
个日期。
count
表示最终结果的数量。step
可以使用负值,如#duration(-10, 5, 0, 0)
。计算过程中会计算时间,但最终结果只取日期部分。
// 2022/1/1、2022/1/2、2022/1/3
List.Dates(#date(2022, 1, 1), 3, #duration(1, 0, 0, 0))
// 2022/1/1、2022/1/2、2022/1/4、2022/1/5、2022/1/7
List.Dates(#date(2022, 1, 1), 5, #duration(1, 12, 0, 0))
List.DateTimes
List.DateTimes(start as datetime, count as number, step as duration) as list
从日期start
开始,按照步长step
最终生成count
个日期。
count
表示最终结果的数量。step
可以使用负值,如#duration(-10, 5, 0, 0)
。
List.DateTimeZones
List.DateTimeZones(start as datetimezone, count as number, step as duration) as list
从日期start
开始,按照步长step
最终生成count
个日期。
count
表示最终结果的数量。step
可以使用负值,如#duration(-10, 5, 0, 0)
。
List.Difference
List.Difference(list1 as list, list2 as list, optional equationCriteria as any) as list
将list2
中的项从list1
中移除并返回剩余的项组成的列表。
该函数按照list2
的内容依次从list1
中删除单个项,如果某个项在list2
中出现多次,list1
中也可能删除多次。因此最终结果可能依然包含list2
中的内容。
D({1, 2, 1}, {1, 2}) = {1}
D({1, 2, 1}, {1, 1, 1}) = {2}
该函数对应“差集”。
参数equationCriteria
是一个函数,函数原型(list1Orlist2Item as any) as any
,该函数会在比较两个数组的项值前进行转换并使用转换后的结果进行比较,如果相同则将值从list1
中移除。
// {}
List.Difference({null}, {null})
// {null}
List.Difference({null}, {})
// {1, 3, 4}
List.Difference({1, 1, 2, 3, 4}, {1, 2})
List.Difference({1, 1, 2, 3, 4}, {1, 2, 666})
// {3, 4}
List.Difference({1, 1, 2, 3, 4}, {1, 2, 1})
// {1}
List.Difference({1, 1, 2}, {11, 12}, (x) => Number.Mod(x, 10))
// {"abc", "abcs"}
List.Difference(
{"abc", "ab", "abcs"},
{1, 2},
(x) => if x is text then Text.Length(x) else x
)
List.Distinct
List.Distinct(list as list, optional equationCriteria as any) as list
对列表list
进行去重。
参数equationCriteria
用于转换列表list
中的值并使用结果用于计算,函数原型(listItem as any) as any
。位置靠前的值将作为结果项输出。
该函数遇到错误就会中止,只能计算到错误和错误之前的部分。
// {"a", "A"}
List.Distinct({"a", "A"})
List.Distinct({"a", "A"}, Comparer.Ordinal)
// {"a"}
List.Distinct({"a", "A"}, Comparer.OrdinalIgnoreCase)
// {"A"}
List.Distinct({"A", "a"}, Comparer.OrdinalIgnoreCase)
// {{1, 2}, {4, 2}, {4, 3}}
List.Distinct({{1, 2}, {4, 2}, {1, 2}, {4, 3}})
// {1, 2, -1}
List.Distinct({1, 2, -1})
// {1, 2}
List.Distinct({1, 2, -1}, each Number.Abs(_))
// {-1, 2}
List.Distinct({-1, 2, 1}, each Number.Abs(_))
该函数仅对必需的部分进行计算,例如下面的表达式,仅计算出前三个不重复值即可(即只会遍历前4个项),因此不会触发错误。
List.Distinct({1, 2, 2, 3, 1, error "a"}){2}
List.Durations
List.Durations(start as duration, count as number, step as duration) as list
从日期start
开始,按照步长step
最终生成count
个持续时间。
count
表示最终结果的数量。step
可以使用负值,如#duration(-10, 5, 0, 0)
。
List.Durations(#duration(0, 0, 0, 0), 5, #duration(0, 1, 0, 0))
List.FindText
List.FindText(list as list, text as text) as list
查找列表list
中包含文本text
的项,结果是所有结果组成的列表。
列表中可以存在非文本类型,非文本类型会被跳过。
// {"123", "312"}
List.FindText({1, "123", "2", "312"}, "12")
List.First
List.First(list as list, optional defaultValue as any) as any
返回列表第一个项。
在数组为空时,如果指定了defaultValue
,则返回defaultValue
,否则返回null
。
List.FirstN
List.FirstN(list as list, countOrCondition as any) as any
返回列表的前N项。
countOrCondition
可以是:
- 数字:前N项。
- 0:返回空列表。
- 超过项个数:返回全部项。
- 函数:从开头向后所有满足条件的项,一旦遇到不满足的就中止;如果第一个项不满足条件则返回空列表。
// {1, 2, 3}
List.FirstN({1..9}, 3)
List.FirstN({1..9}, each _ < 4)
// {}
List.FirstN({1..9}, 0)
List.FirstN({1..9}, each _ > 4)
List.Generate
List.Generate(
initial as function,
condition as function,
next as function,
optional selector as nullable function
) as list
函数initial
的结果作为初始值,循环判断是否满足条件函数condition
并确定是否继续执行函数next
,next
函数会将当前值追加到结果列表并更新当前值。还可以指定函数selector
来对next
产生的结果进行进一步处理,以确定如何更新初始值。
参数 | 类型 | 说明 |
---|---|---|
initial | 函数 | 返回初始值的函数,之后每次循环都会更新该值。 函数原型:() as any 。 |
condition | 函数 | 判断是否继续循环,返回true 时会继续循环。 函数原型:(_ as any) as logical 。 |
next | 函数 | 计算下一个值并更新。 函数原型:(_ as any) as any 。 |
selector | 函数 | 可选。计算输出值,如果不指定则输出next 的结果。函数原型: (_ as any) as any 。 |
- 执行初始化函数
initial
生成初始值(之后称之为循环变量)。 - 进行循环体。
- 将循环变量传给
condition
进行计算,如果得到true
则进行循环,否则退出循环。 - 如果存在
selector
函数,则将循环变量交给selector
处理并将结果追加到结果列表。否则,直接将循环变量追加到结果列表。 - 执行
next
函数,计算下一个用于循环的循环变量。
- 将循环变量传给
- 返回列表。
为了转换思想,可以对比下面两种等效的写法,一个为M,一个为python的循环:
i = 0
j = 100
result = []
while i < 10:
result.append(i + j)
i += 2
// 结果对应上面的result
List.Generate(
() => [i = 0, j = 10], // 1. 对应while之前的初始化
each [i] < 10, // 2. 判断是否继续循环
each [i = [i] + 2, j = 10], // 4. 更新下一个值,回到第2步
each [i] + [j] // 3. 输出值并追加到结果列表
)
示例:
// 0-9
List.Generate(() => 0, each _ < 10, each _ + 1)
// 0-9平方和
List.Generate(() => 0, each _ < 10, each _ + 1, each _ * _)
// 0-9偶数
List.Generate(() => 0, each _ < 10, each _ + 2)
// 0-9之间任意初始值,返回偶数
List.Generate(
() => 3,
each _ < 10 - Number.Mod(_, 2),
each _ + 2,
each _ + Number.Mod(_, 2)
)
// 101..110
List.Generate(
() => [n=1],
each [n] <= 10,
each [n = [n] + 1],
each [n] + 100
)
List.InsertRange
List.InsertRange(list as list, index as number, values as list) as list
在列表list
的索引index
处插入列表value
,之后的内容向后移动。
index
取值范围。
0
:列表开头插入最大索引
:列表结尾插入其它
:列表内部插入
// {0, 1, 666, 999, 2, 3}
List.InsertRange({0..3}, 2, {666, 999})
// {0, 1, 2, 3, 666, 999}
List.InsertRange({0..3}, 4, {666, 999})
List.Intersect
List.Intersect(lists as list, optional equationCriteria as any) as list
返回列表lists
中所有列表的交集。
参数equationCriteria
用于转换列表list
中的值并使用结果用于计算。转换以后输出先出现的项。
// {3, 4}
List.Intersect({{1..5}, {2..4}, {4, 1, 3}})
// {4, 3}
List.Intersect({{4, 1, 3}, {1..5}, {2..4}})
// {}
List.Intersect({{2..4}, {-3, -4}})
// {3, 4}
List.Intersect({{2..4}, {-3, -4}}, each Number.Abs(_))
// {-3, -4}
List.Intersect({{-3, -4}, {2..4}}, each Number.Abs(_))
List.IsDistinct
List.IsDistinct(list as list, optional equationCriteria as any) as logical
检查列表list
的项是否唯一,唯一返回true
,否则为false
。
空列表会返回true
。
包含错误时会返回错误。
参数equationCriteria
用于转换列表list
中的值并使用结果用于计算。
// true
List.IsDistinct({3, -1, 1, 5})
// false
List.IsDistinct({3, -1, 1, 5}, each Number.Abs(_))
List.IsEmpty
List.IsEmpty(list as list) as logical
当列表list
为空列表时返回true
,否则返回false
。
List.Last
List.Last(list as list, optional defaultValue as any) as any
取列表list
的最后一个项。
当列表是空列表时,如果指定了defaultValue
,返回defaultValue
,否则返回null
。
List.LastN
List.LastN(list as list, optional countOrCondition as any) as any
返回列表的最后N项。
countOrCondition
可以是:
- 数字:最后N项。
- 0:返回空列表。
- 超过项个数:返回全部项。
- 函数:从结尾向前返回所有满足条件的项,一旦遇到不满足的就中止;如果最后一项不满足条件则返回空列表。
// {7, 8, 9}
List.LastN({1..9}, 3)
List.LastN({1..9}, each _ > 6)
// {}
List.LastN({1..9}, 0)
List.LastN({1..9}, each _ < 6)
// {}
List.LastN({-1, 0, 1, -2}, each _ > 0)
// {-3, -2}
List.LastN({-1, 0, 1, -3, -2}, each _ < 0)
List.MatchAll
List.MatchesAll(list as list, condition as function) as logical
列表list
中的每个项传入函数condition
进行测试且都为true
则返回true
。
List.MatchesAll({3, 5, 7}, each Number.Mod(_, 2) = 1)
List.MatchesAll({3..7}, each Number.Mod(_, 2) = 1)
List.MatchAny
List.MatchesAny(list as list, condition as function) as logical
列表list
中的每个项传入函数condition
进行测试,任意一个项能得到true
则返回true
。
注意
一旦列表中的项二参的函数后得到的结果为true
,则立即中止计算并返回true
。
对于包含错误的列表,只要有满足条件的项(即让二参返回true
的项)在错误之前,则正常计算,否则会引发错误而终止计算。
// true
List.MatchesAny({3, error "a", 7}, each Number.Mod(_, 2) = 1)
// error "a"
List.MatchesAny({3, error "a", 7}, each _ > 5)
List.Max
List.Max(
list as list,
optional default as any,
optional comparisonCriteria as any,
optional includeNulls as nullable logical
) as any
比较列表list
中的每个项求出最大值。
当列表list
是空数组时,如果指定了default
,则取default
。如果未指定返回null
。
参数comparisonCriteria
用于设置比较方法。它拥有两个参数,分别表示前后两个列表中的项,结果是1
、0
或-1
。
参数includeNulls
用于指定是否保留null
,默认不保留。当为true
时,会保留null
。当指定为false
或未指定时,会跳过null
。如果保留null
,null
通常会被当做最小值。
// "b"
List.Max({"aa", "b", "abc"})
// "abc"
List.Max({"aa", "b", "abc"}, 0, (x, y) => Number.Sign(Text.Length(x) - Text.Length(y)))
// "b"
List.Max({"aa", "b", "abc"}, 0, (x, y) => Number.Sign(Text.Length(y) - Text.Length(x)))
// 8
List.Max({1, 8, 2, null}, 0, (x, y) => Number.Sign(x - y), false)
List.MaxN
List.MaxN(
list as list,
countOrCondition as any,
optional comparisonCriteria as any,
optional includeNulls as nullable logical
) as list
比较列表list
中的每个项求出最大的几个项组成的列表。
当列表list
是空数组时,如果指定了default
,则取default
。如果未指定返回null
。
参数countOrCondition
可以是:
- 数字:最大的前N个。
- 函数:从排序后的结果开头开始,直到遇到第一个返回
false
的项中止。
参数comparisonCriteria
用于设置比较方法。它拥有两个参数,分别表示前后两个列表中的项,结果是1
、0
或-1
。
参数includeNulls
用于指定是否保留null
,默认不保留。当为true
时,会保留null
。当指定为false
或未指定时,会跳过null
。如果保留null
,null
通常会被当做最小值。
执行顺序:
- 使用
comparisonCriteria
进行排序。 - 从结果的开头开始使用
countOrCondition
截取结果。
// {"abcd", "abc"}
List.MaxN(
{"abcd", "ab", "a", "abc"},
each Text.Length(_) > 2
)
List.MaxN(
{"abcd", "ab", "a", "abc"},
each Text.Length(_) > 2,
(x, y) => Number.Sign(Text.Length(x) - Text.Length(y))
)
// {}
List.MaxN(
{"abcd", "ab", "a", "abc"},
each Text.Length(_) > 2,
(x, y) => Number.Sign(Text.Length(y) - Text.Length(x))
)
// {"a", "ab"}
List.MaxN(
{"abcd", "ab", "a", "abc"},
each Text.Length(_) <= 2,
(x, y) => Number.Sign(Text.Length(y) - Text.Length(x))
)
// {5}
List.MaxN({1, -2, 3, -4, 5, -6}, each Number.Abs(_) > 3)
// {-6, 5, -4}
List.MaxN(
{1, -2, 3, -4, 5, -6},
each Number.Abs(_) > 3,
(x, y) => Number.Sign(Number.Abs(x) - Number.Abs(y))
)
List.Median
List.Median(list as list, optional comparisonCriteria as any) as any
返回列表list
的中值。
如果存在偶数个值,则返回中间两个值中较小的值。如果列表项由date
、time
、datetime
、duration
或number
其中一种组成,则返回两个的均值。
如果列表中为空列表或者都是null
,则返回null
。
该函数始终会跳过null
。
参数comparisonCriteria
用于比较大小。它是一个拥有两个参数的函数,分别待比较的两个值。
// 1.5
List.Median({1, 2, null, null})
// 1.5
List.Median({1, 2, 3, -4}, (x, y) => Number.Sign(x - y))
// 2.5
List.Median({1, 2, 3, -4}, (x, y) => Number.Sign(Number.Abs(x) - Number.Abs(y)))
List.Min
List.Min(
list as list,
optional default as any,
optional comparisonCriteria as any,
optional includeNulls as nullable logical
) as any
比较列表list
中的每个项求出最小值。
当列表list
是空数组时,如果指定了default
,则取default
。如果未指定返回null
。
参数comparisonCriteria
用于设置比较方法。它拥有两个参数,分别表示前后两个列表中的项,结果是1
、0
或-1
。
参数includeNulls
用于指定是否保留null
,默认不保留。当为true
时,会保留null
。当指定为false
或未指定时,会跳过null
。如果保留null
,null
通常会被当做最小值。
List.MinN
List.MinN(
list as list,
countOrCondition as any,
optional comparisonCriteria as any,
optional includeNulls as nullable logical
) as list
比较列表list
中的每个项求出最大的几个项组成的列表。
当列表list
是空数组时,如果指定了default
,则取default
。如果未指定返回null
。
参数countOrCondition
可以是:
- 数字:最大的前N个。
- 函数:从排序后的结果开头开始,直到遇到第一个返回
false
的项中止。
参数comparisonCriteria
用于设置比较方法。它拥有两个参数,分别表示前后两个列表中的项,结果是1
、0
或-1
。
参数includeNulls
用于指定是否保留null
,默认不保留。当为true
时,会保留null
。当指定为false
或未指定时,会跳过null
。如果保留null
,null
通常会被当做最小值。
执行顺序:
- 使用
comparisonCriteria
进行排序。 - 从结果的开头开始使用
countOrCondition
截取结果。
List.Mode
List.Mode(list as list, optional equationCriteria as any) as any
返回列表list
中出现次数最多的项。
可以包含不同的类型。
多个相同次数的项,哪个项第一次出现的位置最靠后的为结果。
参数equationCriteria
用于转换列表list
中的值并使用结果用于计算。
// 3
List.Mode({1, 2, 3, 3, 1})
// 3
List.Mode({1, 2, 3, -3, -3, 1, 1}, each Number.Abs(_))
// -3
List.Mode({1, 2, -3, 3, -3, 1, 1}, each Number.Abs(_))
List.Modes
List.Modes(list as list, optional equationCriteria as any) as list
返回列表list
中出现次数最多的项,如果出现多个次数相同的项,则都返回。
可以包含不同的类型。
多个相同次数的项,按照第一次出现的次序输出结果。
参数equationCriteria
用于转换列表list
中的值并使用结果用于计算。
// {1, 3}
List.Modes({1, 2, 3, 3, 1})
// {1, -3}
List.Modes({1, 2, -3, 3, 1}, each Number.Abs(_))
// {1, 3}
List.Modes({1, 2, 3, -3, 1}, each Number.Abs(_))
List.NonNullCount
List.NonNullCount(list as list) as number
统计列表list
中的非null
项的个数。
List.NonNullCount({3, null})
List.Numbers
List.Numbers(
start as number,
count as number,
optional increment as nullable number
) as list
从数字start
开始,根据步长increment
最终生成count
个项组成的列表。
// {1, 2.5, 4, 5.5}
List.Numbers(1, 4, 1.5)
List.Percentile
List.Percentile(
list as list,
percentiles as any,
optional options as nullable record
) as any
返回列表list
中的一个或多个百分位数。
参数percentiles
可以取值:
- 数字:0~1之间的数字,仅返回一个对应的值。
- 列表:0~1之间的若干个数字,返回它们对应值组成的列表。
参数options
表示插值方法,可以是PercentileMode.Type枚举值或数字:
- 忽略、
null
、PercentileMode.ExcelInc
、1
:默认值。使用与Excel中PERCENTILE.INC兼容的方法。 PercentileMode.ExcelExc
、2
:使用与Excel中PERCENTILE.EXC兼容的方法。PercentileMode.SqlCont
、3
:使用与SQL Server中PERCENTILE_DISC兼容的方法。PercentileMode.SqlDisc
、4
:使用与SQL Server中PERCENTILE_CONT兼容的方法。
// {2}
List.Percentile({0, 100, 2}, {0.5})
// 2.5
List.Percentile({0, 100, 2, 3}, 0.5)
List.Percentile({0, 100, 2, 3}, 0.5, [PercentileMode=PercentileMode.ExcelInc])
// {2.2, 2.8}
List.Percentile({0, 100, 2, 3}, {0.4, 0.6})
// {2.2, 2.5, 2.8}
List.Percentile({0, 100, 2, 3}, {0.4, 0.5, 0.6}, [PercentileMode=PercentileMode.ExcelInc])
// {2, 2.5, 3}
List.Percentile({0, 100, 2, 3}, {0.4, 0.5, 0.6}, [PercentileMode=PercentileMode.ExcelExc])
// {2.2, 2.5, 2.8}
List.Percentile({0, 100, 2, 3}, {0.4, 0.5, 0.6}, [PercentileMode=PercentileMode.SqlCont])
// {2, 2, 3}
List.Percentile({0, 100, 2, 3}, {0.4, 0.5, 0.6}, [PercentileMode=PercentileMode.SqlDisc])
List.PositionOf
List.PositionOf(
list as list,
value as any,
optional occurrence as nullable number,
optional equationCriteria as any
) as any
在列表list
中查找值value
出现的位置(索引从0开始),如果未找到,返回-1。
参数occurrence
可以使用Occurrence.Type枚举值或数字:
- 不指定、
null
、Occurrence.First
、0
:返回第一次出现的位置。 Occurrence.Last
、1
:返回最后一次出现的位置。Occurrence.All
、2
、其他数字
:返回所有的索引列表。此时如果没有结果返回空列表。
参数equationCriteria
用于确定比较方法。它拥有两个参数,分别表示列表中的项和值value
。另外,它返回布尔值用于表示两个值是否相等。
注意
一旦在列表中找到满足条件的值,那么它立即返回对应的索引。
对于包含错误的列表,受三参影响。简单的说就是只要在遍历到错误之前找到需要的值并返回结果,就不会引发错误。
// 2
List.PositionOf({1, 2, 3, 3, 3, 2}, 3)
List.PositionOf({1, 2, 3, 3, 3, 2}, 3, 0)
// 4
List.PositionOf({1, 2, 3, 3, 3, 2}, 3, 1)
// {2, 3, 4}
List.PositionOf({1, 2, 3, 3, 3, 2}, 3, 2)
List.PositionOf({1, 2, 3, 3, 3, 2}, 3, 9)
// {}
List.PositionOf({1, 2, 3, 3, 3, 2}, 5, 9)
// 绝对值相等{2, 3, 4}
List.PositionOf({1, 2, 3, -3, 3, 2}, 3, 2, (x, y) => Number.Abs(x) = Number.Abs(y))
// 所有偶数
List.PositionOf({3, 1, 8, 7, 6, 4}, null, 2, (x, y) => Number.Mod(x, 2) = 0)
List.PositionOf({3, 1, 8, 7, 6, 4}, 2, 2, (x, y) => Number.Mod(x, y) = 0)
List.PositionOfAny
List.PositionOfAny(
list as list,
values as list,
optional occurrence as nullable number,
optional equationCriteria as any
) as any
返回列表values
中的项出现在列表list
中的位置。如果value
的所有项都没找到,返回-1。
参数occurrence
可以使用Occurrence.Type枚举值或数字:
- 不指定、
null
、Occurrence.First
、0
:返回value
所有项第一次出现的位置。 Occurrence.Last
、1
:返回value
所有项最后一次出现的位置。Occurrence.All
、2
、其他数字
:返回所有的索引列表。此时如果没有结果返回空列表。
参数equationCriteria
用于确定比较方法。它拥有两个参数,分别表示列表中的项和值value
。另外,它返回布尔值用于表示两个值是否相等。
注意
一旦在列表中找到满足条件的值,那么它立即返回对应的索引。
对于包含错误的列表,受三参影响。简单的说就是只要在遍历到错误之前找到需要的值并返回结果,就不会引发错误。
// 1
List.PositionOfAny({1, 2, 3, 3, 3, 2}, {2, 3})
// 5
List.PositionOfAny({1, 2, 3, 3, 3, 2}, {2, 3}, 1)
List.PositionOfAny({1, 2, 3, 3, 3, 2}, {3, 2}, 1)
// {1, 2, 3, 4, 5}
List.PositionOfAny({1, 2, 3, 3, 3, 2}, {3, 2, 9}, 2)
// {1, 2, 3, 4, 5}
List.PositionOfAny({1, -2, 3, -3, 3, 2}, {3, 2, 9}, 2, (x, y) => Number.Abs(x) = y)
List.Positions
List.Positions(list as list) as list
返回列表list
的索引值列表。
// {0, 1, 2, 3}
List.Positions({1, error "a", "kk", null})
List.Product
List.Product(
numbersList as list,
optional precision as nullable number
) as nullable number
求数组项的乘积。忽略null
。
如果列表没有项或者都是null
,将会返回null
。
仅支持处理number
类型。
// null
List.Product({null})
// 24
List.Product({null, 2, 3, 4})
precision
参数用于指定计算精度,可以使用Precision.Type枚举值或数字:
Precision.Double
:默认值。浮点精度。Precision.Decimal
:十进制精度。
// 0.30000000000000004
List.Product({0.1, 3})
// 0.3
List.Product({0.1, 3}, Precision.Decimal)
List.Random
List.Random(count as number, optional seed as nullable number) as list
通过指定的种子seed
生成count
个0~1之间的随机数。
参数seed
可以取值:
- 不指定:每次生成的随机数都是唯一的。
- 32位整数:根据数值生成随机数,如果数值不变,那么每次结果都一样。
// 每次刷新都是新的随机
List.Random(5)
// 每次刷新都是不变的
List.Random(5, -9999)
List.Random(5, 6666)
List.Range
List.Range(list as list, offset as number, optional count as nullable number) as list
从列表list
的索引offset
处开始向后选择项。
参数count
用于指定选择项数:
- 不指定:选择到结尾。
- 0~不超过到结尾的项数:按照
count
输出。 - 超过到结尾的项数:到结尾。
// {2..5}
List.Range({0..5}, 2)
// {}
List.Range({0..5}, 2, 0)
// {2..4}
List.Range({0..5}, 2, 3)
// {2..5}
List.Range({0..5}, 2, 666)
List.RemoveFirstN
List.RemoveFirstN(list as list, optional countOrCondition as any) as list
移除列表list
的开头几项。
参数countOrCondition
可以是:
- 不指定或
null
:仅删除第一项。 - 整数:前几项。
- 函数:从开头开始带入函数验证,如果返回
true
就移除,直到遇到第一个false
中止。
// {3..6}
List.RemoveFirstN({0..6}, 3)
List.RemoveFirstN({0..6}, each _ < 3)
List.RemoveItems
List.RemoveItems(list1 as list, list2 as list) as list
将列表list2
中的每个项从list1
中全部移除。
// {2, 5}
List.RemoveItems({1, 2, 3, 1, 5, 3}, {1, 3, 9})
List.RemoveLastN
List.RemoveLastN(list as list, optional countOrCondition as any) as list
移除列表list
的最后几项。
参数countOrCondition
可以是:
- 不指定或
null
:仅删除最后一项。 - 整数:最后几项。
- 函数:从最后开始带入函数验证,如果返回
true
就移除,直到遇到第一个false
中止。
// {0..3}
List.RemoveFirstN({0..6}, 3)
List.RemoveFirstN({0..6}, each _ > 3)
List.RemoveMatchingItems
List.RemoveMatchingItems(
list1 as list,
list2 as list,
optional equationCriteria as any
) as list
将列表list2
中的每个项从list1
中全部移除。
参数equationCriteria
用于指定list1
和list2
项的转换方式,最终使用一二参转换后的数组进行对比。
// {1, -3, 5}
List.RemoveMatchingItems({1, 2, 3, -3, 2, 5}, {2, 3})
// {1, 5}
List.RemoveMatchingItems({1, 2, 3, -3, 2, 5}, {2, 3}, (x) => Number.Abs(x))
// {1, -3.6, 5.5}
List.RemoveMatchingItems({1, 2.5, 3.4, -3.6, 2.1, 5.5}, {2, 3}, (x) => Int32.From(x))
// {"a", "b"}
List.RemoveMatchingItems({"a", "b", "1", "2"}, {"1"}, each Value.FromText(_) is text)
List.RemoveNulls
List.RemoveNulls(list as list) as list
移除列表list
中的所有null
。
List.RemoveRange
List.RemoveRange(
list as list,
index as number,
optional count as nullable number
) as list
在列表list
的索引index
处开始移除count
个项。
参数count
说明:
- 不指定、
null
:删除索引index
位置的项。 1
:同不指定,删除索引index
位置的项。0
:不删除。>1
:从索引index
位置开始删除count
个项。
如果index + count
超过了项个数会引发计算中止,这种情况下,你可能能够访问部分元素。
// {0, 1, 2, 4, 5}
List.RemoveRange({0..5}, 3)
// {0, 1, 2, 5}
List.RemoveRange({0..5}, 3, 2)
// 1
List.RemoveRange({0..5}, 3, 4){1}
// error
List.Count(List.RemoveRange({0..5}, 3, 4))
List.Repeat
List.Repeat(list as list, count as number) as list
将列表list
重复count
次。
// {1..3, 1..3, 1..3}
List.Repeat({1..3}, 3)
List.ReplaceMatchingItems
List.ReplaceMatchingItems(
list as list,
replacements as list,
optional equationCriteria as any
) as list
替换列表list
中的项。
参数replacements
是若干{旧值, 新值}
组成的列表。
参数equationCriteria
用于转换列表list
的项。其结果与replacements
中的旧值对比,若一样则替换成新值。
// {1, 666, 2, 6}
List.ReplaceMatchingItems({1, -2, 2, 6}, {{-2, 666}})
// {1, 666, 666, 6}
List.ReplaceMatchingItems({1, -2, 2, 6}, {{-2, 666}}, (x) => Number.Abs(x))
List.ReplaceRange
List.ReplaceRange(
list as list,
index as number,
count as number,
replaceWith as list
) as list
从列表list
中的索引index
位置开始向后删除共count
个元素并插入列表replaceWith
。
如果index + count
超过list
项个数,将造成函数中止,结果可能能够访问。
// {1, 11, 22}
List.ReplaceRange({1, 2, 3, 4, 5}, 1, 4, {11, 22})
// {1, 11, 22, 5}
List.ReplaceRange({1, 2, 3, 4, 5}, 1, 3, {11, 22})
// error
List.ReplaceRange({1, 2, 3, 4, 5}, 3, 3, {11, 22}){3}
// 3
List.ReplaceRange({1, 2, 3, 4, 5}, 3, 3, {11, 22}){2}
List.ReplaceValue
List.ReplaceValue(
list as list,
oldValue as any,
newValue as any,
replacer as function
) as list
搜索列表list
中的oldValue
并将其替换为newValue
。
参数replacer
用于指定替换方式:
Replacer.ReplaceValue
:搜索指定的表列,将oldValue
替换为newValue
。Replacer.ReplaceText
:搜索指定的表列中的文本,如果列中的值包含oldValue
,则将列值的oldValue
部分替换成newValue
。- 自定义函数:拥有三个参数的函数,三个参数分别表示当前搜索的值、
oldValue
和newValue
,返回用于替换的值。
// {1, 222, -2, 6}
List.ReplaceValue({1, 2, -2, 6}, 2, 222, Replacer.ReplaceValue)
List.ReplaceValue({"AbcDef", "ABCDEF", "ABcdEF"}, "CDE", "+", Replacer.ReplaceText)
// {1, 222, 222, 6}
List.ReplaceValue({1, 2, -2, 6}, 2, 222, (v, x, y) => if Number.Abs(v) = x then y else v)
List.Reverse
List.Reverse(list as list) as list
翻转列表。
List.Select
List.Select(list as list, selection as function) as list
返回列表list
中匹配selection
的项。
该函数遍历一参的所有项,并将项值传给二参,如果二参返回true
则保留,否则忽略,最终返回所有保留项组成的列表。
参数selection
是一个仅有一个参数的函数,函数原型(x as any) as nullable logical
,其中x
表示List.Select
一参中的项。selection
通常情况下返回null
将被视为false
,但在某些特殊场景中会报错。
// {2, 4}
List.Select({1..5}, each Number.Mod(_, 2) = 0)
List.Count(List.Select({null, 1, 2, 3}, each _ >= 2))
Table.Group(
#table({"c1", "c2"}, {{"a", null}, {"a", 1}, {"b", 3}}),
"c1",
{
{"g1", each List.Count(List.Select([c2], each _ > 0))},
{"g2", each [y = List.Count(List.Select([c2], each _ > 0))][y]},
{"g3", each Table.RowCount(Table.SelectRows(_, each [c2] > 0))}
}
)
List.Single
List.Single(list as list) as any
返回列表list
中的唯一一个项。
如果没有项或者拥有多个项将会引发异常。
List.SingleOrDefault
List.SingleOrDefault(list as list, optional default as any) as any
返回列表list
中的唯一一个项。
参数default
用于设置当list
是空列表时的替代值。
当列表list
超过一个项时,一定会引发异常,不管是否设置default
。
List.Skip
List.Skip(list as list, optional countOrCondition as any) as list
跳过列表list
开头的若干项。
如果是空列表,则返回空列表。
参数countOrCondition
可以取值:
- 不指定:跳过第一个项。
- 数字:跳过若干个项。如果超过项个数,将会返回空列表。
- 函数:从开头开始使用函数验证项,直到遇到第一个返回
false
的项中止。
// {}
List.Skip({0..5}, 66)
// {3..5}
List.Skip({0..5}, 3)
List.Skip({0..5}, each _ < 3)
List.Sort
List.Sort(list as list, optional comparisonCriteria as any) as list
对列表list
进行排序。
参数comparisonCriteria
用于控制排序方式:
- 可使用
Order.Descending
或Order.Ascending
(默认值)指定降序或升序。 - 可使用具有单个形参的函数转换列表中的项。
- 可使用若干个
{转换函数, 排序方式}
列表组成的列表按照次序优先级进行排序,排序方式可选。 - 可使用仅包含若干个转换函数的列表按照先后优先级进行排序,该方式不能指定升降序。
- 可使用具有两个形参的函数比较列表中的两个值。
如果值转换后相同或比较结果相同,将会按照出现的次序进行排序。
// {5, 3, 2, 0, -3}
List.Sort({2, -3, 5, 3, 0}, Order.Descending)
// {0, 2, -3, 3, 5}
List.Sort({2, -3, 5, 3, 0}, each Number.Abs(_))
// {-9, -3, 0, 5, 3, 2}
List.Sort(
{2, -3, 5, -9, 3, 0},
{
{each Number.Sign(_), Order.Ascending},
{each Number.Abs(_), Order.Descending}
}
)
// {-3, -9, 0, 2, 3, 5}
List.Sort({2, -3, 5, -9, 3, 0}, {{each Number.Sign(_)}, {each Number.Abs(_)}})
List.Sort({2, -3, 5, -9, 3, 0}, {each Number.Sign(_), each Number.Abs(_)})
// {0, 2, -3, 3, 5, -9}
List.Sort({2, -3, 5, -9, 3, 0}, (x, y) => Number.Sign(Number.Abs(x) - Number.Abs(y)))
// {0, 2, 3, -3, 5, -9}
List.Sort({2, 3, 5, -9, -3, 0}, (x, y) => Number.Sign(Number.Abs(x) - Number.Abs(y)))
// {-9, 5, -3, 3, 2, 0}
List.Sort({2, -3, 5, -9, 3, 0}, (x, y) => Number.Sign(Number.Abs(y) - Number.Abs(x)))
// {-9, 5, 3, -3, 2, 0}
List.Sort({2, 3, 5, -9, -3, 0}, (x, y) => Number.Sign(Number.Abs(y) - Number.Abs(x)))
List.Split
List.Split(list as list, pageSize as number) as list
将列表list
拆分成包含pageSize
个项的列表,拆分后的列表按照顺序组成新的列表。
// {{0, 1}, {2, 3}, {4}}
List.Split({0..4}, 2)
// {{0..4}}
List.Split({0..4}, 6)
List.StandardDeviation
List.StandardDeviation(numbersList as list) as nullable number
返回列表numbersList
所有项的标准差。会忽略所有null
。
列表numbersList
必须全部是number
(也可以是null
,但会被忽略),如果不是会引发错误。
List.Sum
List.Sum(list as list, optional precision as nullable number) as any
求数组项的和。忽略null
。
如果列表没有项或者都是null
,将会返回null
。
仅支持处理number
、duration
类型的值,且必须是同一类型。
precision
参数用于指定计算精度,可以使用Precision.Type枚举值或数字:
Precision.Double
:默认值。浮点精度。Precision.Decimal
:十进制精度。
// 6
List.Sum({5, 1, null})
// null
List.Sum({null})
// 3.06:00:00
List.Sum({#duration(1, 0, 0, 0), #duration(2, 6, 0, 0)})
List.Times
List.Times(start as time, count as number, step as duration) as list
从时间start
开始,按照步长step
最终生成count
个时间。
count
表示最终结果的数量。step
可以使用负值,如#duration(-10, 5, 0, 0)
。计算过程中会计算日期,但最终结果只取时间部分。
// {#time(5, 0, 0), #time(17, 0, 0), #time(5, 0, 0)}
List.Times(#time(5, 0, 0), 3, #duration(1, 12, 0, 0))
List.Transform
List.Transform(list as list, transform as function) as list
遍历列表list
的所有项,将其代入函数transform
中进行计算,返回计算结果组成的列表。
// {0, 1, 2, 3}
List.Transform({1, 2, 3, 4}, each _ - 1)
List.TransformMany
List.TransformMany(
list as list,
collectionTransform as function,
resultTransform as function
) as list
对列表list
应用函数collectionTransform
(函数原型(listItem as any) as any
)并用其生成结果列表,函数resultTransform
(函数原型(listItem as any, collItem as any) as any
)拥有两个参数,一个接受列表list
的每一个项,另一个接受上一步产生的结果列表的每个项,所有的结果最终合并到一个列表中输出。
- 循环
list
。- 按顺序取出
list
中的项x
。 - 对
x
使用函数collectionTransform
,生成新的列表list2
。 - 循环
list2
。- 按顺序取出列表
list2
的某个项y
。 - 执行函数
resultTransform
,传入x
、y
并生成值。 - 将值追加到最终结果。
- 按顺序取出列表
- 按顺序取出
- 返回最终结果。
该函数生成的结果项个数是数组list
的项个数和每次执行collectionTransform
生成的项个数的乘积之和。
示例:
// 1..3和1..5的笛卡尔积
List.TransformMany({1..3}, each {1..5}, (x, y) => Text.From(x) & "-" & Text.From(y))
List.Union
List.Union(lists as list, optional equationCriteria as any) as list
合并列表lists
中的列表并在合并过程中对项去重。
仅能合并一层。
参数equationCriteria
可以对项进行转换,转换后的值用于比较和合并。
// {1, 2, 3, -3, 4}
List.Union({{1..3}, {2, -3, 4}, {2}})
// {1, 2, 3, 4}
List.Union({{1..3}, {2, -3, 4}, {2}}, (x) => Number.Abs(x))
List.Zip
List.Zip(lists as list) as list
转置列表lists
。
如果列表lists
中的列表项数不同,将会填充null
。
// {{1, 4}, {2, 5}, {3, 6}}
List.Zip({{1, 2, 3}, {4, 5, 6}})
// {{1, 4}, {2, 5}, {3, null}}
List.Zip({{1, 2, 3}, {4, 5}})