Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an Array.pop_at() method to pop an element at an arbitrary index (3.x) #52143

Merged
merged 1 commit into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions core/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ void Array::push_front(const Variant &p_value) {

Variant Array::pop_back() {
if (!_p->array.empty()) {
int n = _p->array.size() - 1;
Variant ret = _p->array.get(n);
const int n = _p->array.size() - 1;
const Variant ret = _p->array.get(n);
_p->array.resize(n);
return ret;
}
Expand All @@ -373,13 +373,38 @@ Variant Array::pop_back() {

Variant Array::pop_front() {
if (!_p->array.empty()) {
Variant ret = _p->array.get(0);
const Variant ret = _p->array.get(0);
_p->array.remove(0);
return ret;
}
return Variant();
}

Variant Array::pop_at(int p_pos) {
if (_p->array.empty()) {
// Return `null` without printing an error to mimic `pop_back()` and `pop_front()` behavior.
return Variant();
}

if (p_pos < 0) {
// Relative offset from the end
p_pos = _p->array.size() + p_pos;
}

ERR_FAIL_INDEX_V_MSG(
p_pos,
_p->array.size(),
Variant(),
vformat(
"The calculated index %s is out of bounds (the array has %s elements). Leaving the array untouched and returning `null`.",
p_pos,
_p->array.size()));

const Variant ret = _p->array.get(p_pos);
_p->array.remove(p_pos);
return ret;
}

Variant Array::min() const {
Variant minval;
for (int i = 0; i < size(); i++) {
Expand Down
1 change: 1 addition & 0 deletions core/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Array {
void push_front(const Variant &p_value);
Variant pop_back();
Variant pop_front();
Variant pop_at(int p_pos);

Array duplicate(bool p_deep = false) const;

Expand Down
2 changes: 2 additions & 0 deletions core/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ struct _VariantCall {
VCALL_LOCALMEM1(Array, push_front);
VCALL_LOCALMEM0R(Array, pop_back);
VCALL_LOCALMEM0R(Array, pop_front);
VCALL_LOCALMEM1R(Array, pop_at);
VCALL_LOCALMEM1(Array, append);
VCALL_LOCALMEM1(Array, append_array);
VCALL_LOCALMEM1(Array, resize);
Expand Down Expand Up @@ -1892,6 +1893,7 @@ void register_variant_methods() {
ADDFUNC1R(ARRAY, BOOL, Array, has, NIL, "value", varray());
ADDFUNC0RNC(ARRAY, NIL, Array, pop_back, varray());
ADDFUNC0RNC(ARRAY, NIL, Array, pop_front, varray());
ADDFUNC1RNC(ARRAY, NIL, Array, pop_at, INT, "position", varray());
ADDFUNC0NC(ARRAY, NIL, Array, sort, varray());
ADDFUNC2NC(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray());
ADDFUNC0NC(ARRAY, NIL, Array, shuffle, varray());
Expand Down
8 changes: 8 additions & 0 deletions doc/classes/Array.xml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@
Returns the minimum value contained in the array if all elements are of comparable types. If the elements can't be compared, [code]null[/code] is returned.
</description>
</method>
<method name="pop_at">
<return type="Variant" />
<argument index="0" name="position" type="int" />
<description>
Removes and returns the element of the array at index [code]position[/code]. If negative, [code]position[/code] is considered relative to the end of the array. Leaves the array untouched and returns [code]null[/code] if the array is empty or if it's accessed out of bounds. An error message is printed when the array is accessed out of bounds, but not when the array is empty.
[b]Note:[/b] On large arrays, this method can be slower than [method pop_back] as it will reindex the array's elements that are located after the removed element. The larger the array and the lower the index of the removed element, the slower [method pop_at] will be.
</description>
</method>
<method name="pop_back">
<return type="Variant" />
<description>
Expand Down