Vim脚本之列表类型

复合数据类型之列表

  • 列表是事物的有序集合, 这里是事物是各种类型的值,甚至是混合项目.
  • 列表是引用类型, 就如同java中的对象一样.
  • 在必要的时候可以使用copy() 和 deepcopy()

建立列表

1
2
3
4
5
6
" 建立空列表
let alist = []
" 建立一个字符串列表
let strlist = ['app', 'root', 'qml']
" 多维列表
let nestlist = [[11, 12], [21, 22], [33, 43]]

列表索引

索引从0开始; 索引可以为负数, -1表示最后一个项目.

1
2
3
4
5
6
7
let item = strlist[0] " 得到第一个项目
let item = strlist[2] " 得到第三个项目
let item = nestlist[1][1] " 22
let last = strlist[-1]

echo get(strlist, 0)
echo get(strlist, 4, 'none') " 如果要找的索引超过范围,则返回none

列表切片

通过指定首末俩个索引, 获取列表的一部分.

1
2
3
4
5
6
7
8
9
10
11
12
let testlist = [1, 2, 4, 'one', 'three']

let shortlist = testlist[2 : -1] " [4, 'one', 'three']

" 如果首索引省略,则为0; 末索引省略为-1;
let endlist = testlist[3:] " ['one', 'three']
let shortlist = testlist[2:3] " [4, 'one']
let otherlist = mylist[:] " 复制列表

" 如果末索引大于等于列表的长度, 使用长度减1
let mylist = [4, 6, 8, 9]
echo mylist[2: 9] "[8, 9]

列表解包

将列表中的值存入变量.

1
2
3
4
5
6
let [var1, var2, var3] = mylist

" 相当于
let var1 = mylist[0]
let var2 = mylist[1]
let var3 = mylist[2:]

列表修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
" 用 add() 函数添加item
let alist = []
call add(alist, 'foo')
call add(alist, 'bar')
echo alist

" 用 '+' 添加item
let alist = ['user', 'password']
let alist += ['name', 'other']
echo alist

" 用extend() 扩展
let alist = ['one']
call extend(alist, ['two', 'three'])
echo alist
" ['one', 'two', 'three']

" 注意: 如果上面的用add()扩展,效果就不一样
let alist = ['one']
call add(alist, ['two', 'three'])
echo alist
" ['one', ['two', 'three']]

" 删除项目
let i = remove(alist, 3)
unlet alist[3]
let l = remove(alist, 3, -1)
unlet alist[3: ]
call filter(list, 'v:val !~ "x"') " 删除有x的项目

" 改变顺序
call sort(alist)
call reverse(alist)

注意: add()的第二个参数是作为单个项目被加入的.

列表的循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let alist = ['one', 'two', 'three']
for n in alist
echo n
endfor

" 如果需要循环长度为给定次数的列表,range可以建立这样的列表:
for a in range(3)
echo a
endfor

" range() 产生的列表的第一个项目为0, 最后一个项目比列表的长度小1
" 也可以指定其他参数, 如初始值, 最大值, 步进(正负均可)
for a in range(8, 4, -2)
echo a " 8 6 4
endfor

for line in getline(1, 20)
if line =~ "Date: "
echo matchstr(line, 'Data: \zs.*')
endif
endfor

相关函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let r = call(funcname, list)   " 调用带参数列表的函数
if empty(list) " 检查 list 是否为空
let l = len(list) " list 项目的数量
let big = max(list) " list 项目的最大值
let small = min(list) " list 项目的最小值
let xs = count(list, 'x') " 计算 list 里 'x' 出现的次数
let i = index(list, 'x') " list 第一个 'x' 的位置
let lines = getline(1, 10) " 得到缓冲区十行文本行
call append('$', lines) " 附加若干文本行到缓冲区尾部
let list = split("a b c") " 用字符串中的项目建立列表
let string = join(list, ', ') " 用 list 项目构造字符串
let s = string(list) " list 的字符串表示
call map(list, '">> " . v:val') " 在每个项目前加上 ">> "

" 不要忘记组合使用不同功能可以简化任务。例如,要计算列表中所有数值的总和: >
exe 'let sum = ' . join(nrlist, '+')

更多

更多请:h List