mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
builtin: make array.delete()
reallocate, provide .delete_many()
(#10889)
This commit is contained in:
parent
be7c3965a9
commit
41982053f1
@ -862,6 +862,9 @@ There are further built in methods for arrays:
|
||||
* `a.prepend(arr)` insert elements of array `arr` at beginning
|
||||
* `a.trim(new_len)` truncate the length (if `new_length < a.len`, otherwise do nothing)
|
||||
* `a.clear()` empty the array (without changing `cap`, equivalent to `a.trim(0)`)
|
||||
* `a.delete_many(start, size)` removes `size` consecutive elements beginning with index `start`
|
||||
– triggers reallocation
|
||||
* `a.delete(index)` equivalent to `a.delete_many(index, 1)`
|
||||
* `v := a.first()` equivalent to `v := a[0]`
|
||||
* `v := a.last()` equivalent to `v := a[a.len - 1]`
|
||||
* `v := a.pop()` get last element and remove it from array
|
||||
|
@ -200,15 +200,30 @@ pub fn (mut a array) prepend_many(val voidptr, size int) {
|
||||
|
||||
// delete deletes array element at index `i`.
|
||||
pub fn (mut a array) delete(i int) {
|
||||
a.delete_many(i, 1)
|
||||
}
|
||||
|
||||
// delete_many deletes `size` elements beginning with index `i`
|
||||
pub fn (mut a array) delete_many(i int, size int) {
|
||||
$if !no_bounds_checking ? {
|
||||
if i < 0 || i >= a.len {
|
||||
panic('array.delete: index out of range (i == $i, a.len == $a.len)')
|
||||
if i < 0 || i + size > a.len {
|
||||
endidx := if size > 1 { '..${i + size}' } else { '' }
|
||||
panic('array.delete: index out of range (i == $i$endidx, a.len == $a.len)')
|
||||
}
|
||||
}
|
||||
// NB: if a is [12,34], a.len = 2, a.delete(0)
|
||||
// should move (2-0-1) elements = 1 element (the 34) forward
|
||||
unsafe { C.memmove(a.get_unsafe(i), a.get_unsafe(i + 1), (a.len - i - 1) * a.element_size) }
|
||||
a.len--
|
||||
old_data := a.data
|
||||
new_size := a.len - size
|
||||
new_cap := if new_size == 0 { 1 } else { new_size }
|
||||
a.data = vcalloc(new_cap * a.element_size)
|
||||
unsafe { C.memcpy(a.data, old_data, i * a.element_size) }
|
||||
unsafe {
|
||||
C.memcpy(&byte(a.data) + i * a.element_size, &byte(old_data) + (i + size) * a.element_size,
|
||||
(a.len - i - size) * a.element_size)
|
||||
}
|
||||
a.len = new_size
|
||||
a.cap = new_cap
|
||||
}
|
||||
|
||||
// clear clears the array without deallocating the allocated data.
|
||||
|
@ -65,6 +65,34 @@ fn test_deleting() {
|
||||
assert a.len == 2
|
||||
}
|
||||
|
||||
fn test_slice_delete() {
|
||||
mut a := [1.5, 2.5, 3.25, 4.5, 5.75]
|
||||
b := a[2..4]
|
||||
a.delete(0)
|
||||
assert a == [2.5, 3.25, 4.5, 5.75]
|
||||
assert b == [3.25, 4.5]
|
||||
a = [3.75, 4.25, -1.5, 2.25, 6.0]
|
||||
c := a[..3]
|
||||
a.delete(2)
|
||||
assert a == [3.75, 4.25, 2.25, 6.0]
|
||||
assert c == [3.75, 4.25, -1.5]
|
||||
}
|
||||
|
||||
fn test_delete_many() {
|
||||
mut a := [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
b := a[2..6]
|
||||
a.delete_many(4, 3)
|
||||
assert a == [1, 2, 3, 4, 8, 9]
|
||||
assert b == [3, 4, 5, 6]
|
||||
c := a[..a.len]
|
||||
a.delete_many(2, 0) // this should just clone
|
||||
a[1] = 17
|
||||
assert a == [1, 17, 3, 4, 8, 9]
|
||||
assert c == [1, 2, 3, 4, 8, 9]
|
||||
a.delete_many(0, a.len)
|
||||
assert a == []int{}
|
||||
}
|
||||
|
||||
fn test_short() {
|
||||
a := [1, 2, 3]
|
||||
assert a.len == 3
|
||||
|
Loading…
Reference in New Issue
Block a user