Array#delete, but return the array?
Is there a built-in method which performs the same function as Array#delete
but returns self
? I'd like to do it without using a block and clearer than an_ary.-([el])
.
I could monkeypatch one, but it seems like a "compact with arguments" method would be a relatively common 开发者_如何学JAVAdesire?
If you want to mutate the original array, like delete
, here are options:
ary.reject!{|e| e==42 }.something_else
ary.tap{|a| a.delete 42}.something_else
(ary.delete 42;ary).something_else
(ary-=[42]).something_else
If you want a new array to chain from:
ary.reject{|e| e==42 }.something_else
(ary-[42]).something_else
an_ary.-([el])
looks awful.
What about...
an_ary - [el]
?
The most natural way of dealing with mathematical operations is this...
4 - 2
Not this...
4.-(2)
array.reject{|element| element == value_of_element_to_be_deleted}
You can do
my_array.first(n) #1
my_array.last(n) #2
If the elements of the array you want to delete, are at the end (1) or at the beginning (2) of the array.
I had this same question for Array#delete_at
that returned an array with the element at a specified index removed, which is why I ended up here. Looks like it isn't built in. In case anyone else is interested, I quickly wrote this monkey patch (I gave this virtually no thought regarding efficiency, and I originally didn't handle any cases such as negative indices or out of bounds indices...but then I decided to quick throw a couple in there):
class Array
def remove_at(i)
# handle index out of bounds by returning unchanged array
return self if i >= self.length
# remove the i-th element from the end if i is negative
if i < 0
i += self.length
# handle index out of bounds by returning unchanged array
return self if i < 0
end
# Return an array composed of the elements before the specified
# index plus the elements after the specified index
return self.first(i) + self.last(self.length - i - 1)
end
end
test = [0,1,2,3,4,5]
puts test.remove_at(3).inspect
puts test.remove_at(5).inspect
puts test.remove_at(6).inspect
puts test.remove_at(-7).inspect
puts test.remove_at(-2).inspect
I had fun whipping this up, so I figured I might as well post it here :)
I prefer this way:
list = [1, 2, 3, 4, 5]
list.tap { |list| list.delete(2) } # => [1, 3, 4, 5]
The OP doesn't like the look of an_ary.-([el])
... but it really does have a lot going for it.
True...it's a little ugly, but the minus method does the trick concisely, subtracting one array from the other:
ary = [1, 2, 99, 3]
ary.-([99])
or
odds = [1, 3, 5, 7, 9, 99]
ary.-(odds)
The advantage here is that it is completely chainable (unlike .delete
or ary - odds
), so you can do things like:
ary.-(odds).average
Once your eye finds the minus sign, it's much easier to read, understand, and visually spot typos than the .delete_if
or .reject
block constructs.
It also plays well with Ruby's safe navigation operator, &.
, if you might get nil instead of an array. That's something you can't do elegantly with subtracting arrays.
maybe_array&.-(odds)&.average
精彩评论