-
println(arr)
打印数组 -
s := arr.str()
数组转换成字符串 -
arr_copy := arr.clone()
复制数组 -
.filter()
筛选数组nums := [1, 2, 3, 4, 5, 6] even := nums.filter(it % 2 == 0) println(even) // [2, 4, 6] // filter can accept anonymous functions even_fn := nums.filter(fn (x int) bool { return x % 2 == 0 }) println(even_fn)
-
.map()
映射数组words := ['hello', 'world'] upper := words.map(it.to_upper()) // it refers to the current element println(upper) // ['HELLO', 'WORLD'] // map can also accept anonymous functions upper_fn := words.map(fn (w string) string { return w.to_upper() }) println(upper_fn) // ['HELLO', 'WORLD']
-
.any()
/.all()
检测数组nums := [1, 2, 3] println(nums.any(it == 2)) // true println(nums.all(it >= 2)) // false
-
a.repeat(n)
复制数组n
次并拼接 -
a.insert(i, val)
在i
位置插入val
,其余值右移 -
a.insert(i, [3, 4, 5])
在i
位置插入若干元素 -
a.prepend(val)
在开头插入元素,等价于a.insert(0, val)
-
a.prepend(arr)
在开头插入数组 -
a.trim(new_len)
当new_length < a.len
时截断数组 -
a.clear()
清空数组但不改变容量,等价于a.trim(0)
-
a.delete_many(start, size)
从索引start
开始连续删除size
个元素–会触发重新分配 -
a.delete(index)
等价于a.delete_many(index, 1)
-
a.delete_last()
删除最后一个元素 -
a.first()
等价于a[0]
-
a.last()
等价于a[a.len - 1]
-
a.pop()
删除并返回最后一个元素 -
a.reverse()
创建一个新的数组 -
a.reverse_in_place()
将a
中元素逆序,直接存在a
中 -
a.join(joiner)
用字符串joiner
作为分隔符将字符串数组拼接成一个字符串
进一步了解参考 vlib/arrays
对各种数组进行排序非常简单直观。使用特殊变量 a 和 b 来提供自定义的排序条件。
mut numbers := [1, 3, 2]
numbers.sort() // 1, 2, 3
numbers.sort(a > b) // 3, 2, 1
对于结构体数组:
struct User {
age int
name string
}
mut users := [User{21, 'Bob'}, User{20, 'Zarkon'}, User{25, 'Alice'}]
users.sort(a.age < b.age) // sort by User.age int field
users.sort(a.name > b.name) // reverse sort by User.name string field
V 还支持通过 sort_with_compare
方法自定义排序。这需要一个定义排序顺序的比较函数。用于通过自定义排序规则同时对多个字段进行排序。下面的代码按 name
升序和 age
降序对数组进行排序。
struct User {
age int
name string
}
mut users := [User{21, 'Bob'}, User{65, 'Bob'}, User{25, 'Alice'}]
custom_sort_fn := fn (a &User, b &User) int {
// return -1 when a comes before b
// return 0, when both are in same order
// return 1 when b comes before a
if a.name == b.name {
if a.age < b.age {
return 1
}
if a.age > b.age {
return -1
}
return 0
}
if a.name < b.name {
return -1
} else if a.name > b.name {
return 1
}
return 0
}
users.sort_with_compare(custom_sort_fn)
切片就是父数组的一部分。最原始的定义为:指代由 ..
操作符分隔的两个索引值之间的一系列元素,左闭右开。右边的索引值必须大于等于左边的索引值。
若右索引值缺失则默认为数组长度,若左索引值缺失默认为 0。
nums := [0, 10, 20, 30, 40]
println(nums[1..4]) // [10, 20, 30]
println(nums[..4]) // [0, 10, 20, 30]
println(nums[1..]) // [10, 20, 30, 40]
在 V 中切片就是数组本身(它们不是不同的数据类型)。所以所有的数组操作都可以用在切片上。比如可以将同类型的数组 push
到切片上:
array_1 := [3, 5, 4, 7, 6]
mut array_2 := [0, 1]
array_2 << array_1[..3]
println(array_2) // `[0, 1, 3, 5, 4]`
刚创建时切片相应元素地址与父数组一致。不过无论父数组设置如何,切片总是以最小容量创建,即 cap == len
。这会导致,当切片大小增加时,它会立即重新分配内存并复制到另一个内存位置,从而独立于父数组(增大时复制)。特别注意的是,将元素 push
到切片不会改变父数组:
mut a := [0, 1, 2, 3, 4, 5]
mut b := a[2..4]
b[0] = 7 // `b[0]` is referring to `a[2]`
println(a) // `[0, 1, 7, 3, 4, 5]`
b << 9
// `b` has been reallocated and is now independent from `a`
println(a) // `[0, 1, 7, 3, 4, 5]` - no change
println(b) // `[7, 3, 9]`
向父数组添加元素可能也可能不会改变其与子切片的独立性。结果取决于父数组的容量,并且是可预见的:
mut a := []int{len: 5, cap: 6, init: 2}
mut b := a[1..4]
a << 3
// no reallocation - fits in `cap`
b[2] = 13 // `a[3]` is modified
a << 4
// a has been reallocated and is now independent from `b` (`cap` was exceeded)
b[1] = 3 // no change in `a`
println(a) // `[2, 2, 2, 13, 2, 3, 4]`
println(b) // `[2, 3, 13]`
如果你想直接创建一个与父数组独立的切片,可以调用 .clone()
方法:
mut a := [0, 1, 2, 3, 4, 5]
mut b := a[2..4].clone()
b[0] = 7 // NB: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
println(a) // [0, 1, 2, 3, 4, 5]
println(b) // [7, 3]
V 支持负索引的数组或字符串切片。负索引指从数组末尾往前数,例如 -3
等于 array.len() - 3
。但负索引切片与正常切片句法不同,需要在数组名与方括号之间增加 gate
,像这样 a#[..-3]
。gate
表明这是一种不同类型的切片,你应该记住结果在数组中“锁定”了。返回的切片尽管始终是有效数组,但它可能为空:
a := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
println(a#[-3..]) // [7, 8, 9]
println(a#[-20..]) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
println(a#[-20..-8]) // [0, 1]
println(a#[..-3]) // [0, 1, 2, 3, 4, 5, 6]
// empty arrays
println(a#[-20..-10]) // []
println(a#[20..10]) // []
println(a#[20..30]) // []
你可以链式调用数组的方法,比如 .filter()
与 .map()
,并使用 it
这一内置变量得到一个经典的 map/filter
功能示例:
// using filter, map and negatives array slices
files := ['pippo.jpg', '01.bmp', '_v.txt', 'img_02.jpg', 'img_01.JPG']
filtered := files.filter(it#[-4..].to_lower() == '.jpg').map(it.to_upper())
// ['PIPPO.JPG', 'IMG_02.JPG', 'IMG_01.JPG']