You can use the adverb :delete
in Perl 6 to delete an array element if you know its index:
my @letters = <a b c>; @letters[0]:delete; say @letters
# OUTPUT: «[(Any) b c]»
However, you can't do that if you don't know the index:
my @letters = <a b c>; $_:delete if $elem eq 'a' for @letters
#ERROR! → Variable '$_:delete' is not declared
If you declare the loop variable is rw
still the same problem:
my @letters = <a b c>; for @letters -> $l is rw { $l:delete if $l eq 'a' }; say @letters
#ERROR! → Variable '$l:delete' is not declared
There does not seem to be another way of deleting array elements. The equivalent for Perl 5's delete
points, in fact, to that adverb. You could use splice
but once again you would have to know the index. The implementation seems to be this function, DELETE-POS
, which effectively needs to know the array index.
So the question is, as in the title, is there a way of deleting an array (or, for that matter, associative array) element if you have the handle of just the element itself, not its index?
Using ArrayList Get the array and the index. Form an ArrayList with the array elements. Remove the specified index element using remove() method. Form a new array of the ArrayList using mapToInt() and toArray() methods.
If you want to remove an item from an array, you can use the pop() method to remove the last element or the shift() method to remove the first element.
You can use the pop() method to remove specific elements of a list. pop() method takes the index value as a parameter and removes the element at the specified index. Therefore, a[2] contains 3 and pop() removes and returns the same as output.
In order to remove an element from an array, we can use unset() function which removes the element from an array and then use array_values() function which indexes the array numerically automatically.
Depends on what you call delete
. Internally, on arrays, doing a DELETE-POS
binds the element in the array to nqp::null
, which will discard any container living at that position. At the HLL level, this is represented by the type of the array:
my Str @letters = <a b c>;
@letters[1]:delete;
say @letters; # [a (Str) c]
However you can achieve the same effect by assigning Nil
:
my Str @letters = <a b c>;
@letters[1] = Nil;
say @letters; # [a (Str) c]
In this case, the container at that element stays the same, you just let it revert to its "natural" state. And if you're content with that type of deletion, you can also use that in your loop:
my Str @letters = <a b c>;
$_ = Nil if $_ eq "b" for @letters;
say @letters; # [a (Str) c]
When I said: revert to its natural state, this also includes any default value:
my Str @letters is default<foo> = <a b c>;
$_ = Nil if $_ eq "b" for @letters;
say @letters; # [a foo c]
If you want to really eradicate the elements from the list without keeping the existing elements at their positions, you can of course use grep
:
my @letters = <a b c>;
@letters .= grep: * ne "b";
say @letters; # [a c]
But that does not seem like what you intended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With