Just use .splice():
for index, elem in @arr
@arr.splice index, 1 if elem is val
If you don't care about Internet Explorer 7 or 8, you can simplify it even more:
@arr.splice @arr.indexOf(val), 1
This assumes that the element is present in the array, otherwise it would remove the very last element. In case you need to check if it is present, you can use a little trick:
@arr.splice (@arr.indexOf(val)+1 or @arr.length+1)-1, 1
Compared to the "coffee only" filter solution, you get 4-8 times the performance (in Chrome):
Removing 5 random elements from an array with 10.000.000 integers
cumulative execution time after each removed element
filter method
- 197ms
- 422ms
- 626ms
- 847ms
- 1087ms
splice method
- 33ms
- 83ms
- 142ms
- 198ms
- 255ms
splice and indexOf method
- 27ms
- 70ms
- 88ms
- 116ms
- 134ms
Test code - quick and dirty (doesn't account for randomly selecting the same value twice):
log "coffee method"
arr = [0..9999999]
length = arr.length
start = new Date().getTime()
for num in [1..5]
val = Math.round(Math.random() * length)
do (val) -> arr = (x for x in arr when x isnt val)
log new Date().getTime()-start+"ms"
log "splice method"
arr = [0..9999999]
length = arr.length
start = new Date().getTime()
for num in [1..5]
val = Math.round(Math.random() * length)
for index, elem in arr
arr.splice index, 1 if elem is val
log new Date().getTime()-start+"ms"
log "splice method with indexOf()"
arr = [0..9999999]
length = arr.length
start = new Date().getTime()
for num in [1..5]
val = Math.round(Math.random() * length)
arr.splice arr.indexOf(val), 1
log new Date().getTime()-start+"ms"
Demo: http://jsfiddle.net/j9CZz/1/