I have an array of elements in Ruby
[2,4,6,3,8]
I need to remove elements with value 3
for example
How do I do that?
active record
method delete
ImranNaqvi 2016-11-19 20:31
I think I've figured it out:
a = [2,4,6,3,8]
a.delete(3)
[1, 2, 3, 4, 5] - [3]
which results in => [1, 2, 4, 5]
from irb
- Travis 2012-04-05 19:31
delete
mutates the underlying array whereas -
creates a new array (that is returned to you) without the deleted value. Depending on your use case either approach may make sense - srt32 2014-09-05 16:35
[1,2,3,3] - [3]
returns [1,2]. It will delete 'all' values of 3. Might or might not be what you need.. - Jules Copeland 2014-11-22 12:15
array - subArray
will not work for Array of Arrays, but array.delete(subArray)
will do - Sachin 2016-04-05 12:42
Borrowing from Travis in the comments, this is a better answer:
I personally like
[1, 2, 7, 4, 5] - [7]
which results in=> [1, 2, 4, 5]
fromirb
I modified his answer seeing that 3 was the third element in his example array. This could lead to some confusion for those who don't realize that 3 is in position 2 in the array.
.delete
and -
. .delete
will return the value that was removed from the Array, if any; -
will not. So [ 1, 2, 3 ] - [ 2 ]
will return [ 1, 3 ]
, while [ 1, 2, 3 ].delete( 2 )
will return 2
- Argus9 2014-10-23 16:45
array - subArray
will not work for Array of Arrays, but array.delete(subArray)
will do - Sachin 2016-04-05 12:41
[1,2,3] - [2]
and [1,2,3].delete(2)
is that delete
method modifies the original array, while [1,2,3] - [3]
creates a new array - Timothy Kovalev 2016-11-03 11:08
Another option:
a = [2,4,6,3,8]
a -= [3]
which results in
=> [2, 4, 6, 8]
I'm not sure if anyone has stated this, but Array.delete() and -= value will delete every instance of the value passed to it within the Array. In order to delete the first instance of the particular element you could do something like
arr = [1,3,2,44,5]
arr.delete_at(arr.index(44))
#=> [1,3,2,5]
There could be a simpler way. I'm not saying this is best practice, but it is something that should be recognized.
I like the -=[4]
way mentioned in other answers to delete the elements whose value are 4.
But there is this way:
irb(main):419:0> [2,4,6,3,8,6].delete_if{|i|i==6}
=> [2, 4, 3, 8]
irb(main):420:0>
mentioned somewhere in "Basic Array Operations", after it mentions the map
function.
.delete(6)
Zac 2016-10-06 16:00
-=
way a-=[4]
i.e. a=a-[4]
. [3,4]-[4]
, which I said I liked), but I wanted to mention another possible way - barlop 2016-10-06 16:10
Assuming you want to delete 3 by value at multiple places in an array, I think the ruby way to do this task would be to use the delete_if method:
[2,4,6,3,8,3].delete_if {|x| x == 3 }
You can also use delete_if in removing elements in the scenario of 'array of arrays'.
Hope this resolves your query
You can simply run:
[2,4,6,3,8].delete(3)
A .delete_at(3)
3
here being the position.
Here are some benchmarks:
require 'fruity'
class Array
def rodrigo_except(*values)
self - values
end
def niels_except value
value = value.kind_of?(Array) ? value : [value]
self - value
end
end
ARY = [2,4,6,3,8]
compare do
soziev { a = ARY.dup; a.delete(3); a }
steve { a = ARY.dup; a -= [3]; a }
barlop { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
rodrigo { a = ARY.dup; a.rodrigo_except(3); }
niels { a = ARY.dup; a.niels_except(3); }
end
# >> Running each test 4096 times. Test will take about 2 seconds.
# >> soziev is similar to barlop
# >> barlop is faster than steve by 2x ± 1.0
# >> steve is faster than rodrigo by 4x ± 1.0
# >> rodrigo is similar to niels
And again with a bigger array containing lots of duplicates:
class Array
def rodrigo_except(*values)
self - values
end
def niels_except value
value = value.kind_of?(Array) ? value : [value]
self - value
end
end
ARY = [2,4,6,3,8] * 1000
compare do
soziev { a = ARY.dup; a.delete(3); a }
steve { a = ARY.dup; a -= [3]; a }
barlop { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
rodrigo { a = ARY.dup; a.rodrigo_except(3); }
niels { a = ARY.dup; a.niels_except(3); }
end
# >> Running each test 16 times. Test will take about 1 second.
# >> steve is faster than soziev by 30.000000000000004% ± 10.0%
# >> soziev is faster than barlop by 50.0% ± 10.0%
# >> barlop is faster than rodrigo by 3x ± 0.1
# >> rodrigo is similar to niels
And even bigger with more duplicates:
class Array
def rodrigo_except(*values)
self - values
end
def niels_except value
value = value.kind_of?(Array) ? value : [value]
self - value
end
end
ARY = [2,4,6,3,8] * 100_000
compare do
soziev { a = ARY.dup; a.delete(3); a }
steve { a = ARY.dup; a -= [3]; a }
barlop { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
rodrigo { a = ARY.dup; a.rodrigo_except(3); }
niels { a = ARY.dup; a.niels_except(3); }
end
# >> Running each test once. Test will take about 6 seconds.
# >> steve is similar to soziev
# >> soziev is faster than barlop by 2x ± 0.1
# >> barlop is faster than niels by 3x ± 1.0
# >> niels is similar to rodrigo
I improved Niels's solution
class Array
def except(*values)
self - values
end
end
Now you can use
[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4) # return [1, 2, 3]
irb
console
2.2.1 :007 > [1, 2, 3, 4].except(3, 4)
NoMethodError: undefined method except for [1, 2, 3, 4]:Array
from (irb):7
from /usr/share/rvm/rubies/ruby-2.2.1/bin/irb:11:in <main>
hgsongra 2016-07-06 03:44
class Array; def except(*values); self - values; end; end
- Mark Swardstrom 2017-03-02 17:53
You can also monkey patch it. I never understood why Ruby has an except
method for Hash
but not for Array
:
class Array
def except value
value = value.kind_of(Array) ? value : [value]
self - value
end
end
Now you can do:
[1,3,7,"436",354,nil].except(354) #=> [1,3,7,"436",nil]
Or:
[1,3,7,"436",354,nil].except([354, 1]) #=> [3,7,"436",nil]
value.kind_of(Array)
test. Just use self - Array(value)
- Sasgorilla 2017-03-07 15:02
So when you have multiple occurrences of 3 and you want only to delete the first occurrence of 3, you can simply do some thing as below.
arr = [2, 4, 6, 3, 8, 10, 3, 12]
arr.delete_at arr.index 3
#This will modify arr as [2, 4, 6, 8, 10, 3, 12] where first occurrence of 3 is deleted. Returns the element deleted. In this case => 3.
If you also want to make this deletion operation chainable, so you can delete some item and keep on chaining operations on the resulting array, use tap
:
[2, 4, 6, 3, 8].tap { |ary| ary.delete(3) }.count #=> 4
Non-destructive removal of first occurrence:
a = [2, 4, 6, 3, 8]
n = a.index 3
a.take(n)+a.drop(n+1)
delete
array.delete(3)
not works within ruby on rails controlle - ImranNaqvi 2016-11-19 20:31