값으로 배열에서 하나의 요소를 삭제하는 방법


343

Ruby에 요소 배열이 있습니다.

[2,4,6,3,8]

3예를 들어 값이있는 요소를 제거해야합니다

어떻게합니까?


delete array.delete(3)루비 온 레일 컨트롤러에서 작동하지 않는 이유가 궁금합니다
ImranNaqvi

2
active record방법 으로 인한 것일 수 있습니다delete
ImranNaqvi

답변:


481

나는 그것을 이해했다고 생각합니다.

a = [3, 2, 4, 6, 3, 8]
a.delete(3)
#=> 3
a
#=> [2, 4, 6, 8]

189
나는 개인적으로 같은 [1, 2, 3, 4, 5] - [3]에서 어떤 결과 => [1, 2, 4, 5]에서 irb.
트래비스

24
3의 여러 항목이 있고 그 중 하나만 삭제하려면 어떻게합니까? (이것이 가장 좋을지 묻는 것과 관련이 있습니다)
Navneet

113
.delete ()는 값이 제거 된 수정 된 배열이 아니라 삭제 된 값을 반환한다는 것을 알았습니다.
Joshua Pinter

23
고려해야 할 다른 결과 delete는 기본 배열 을 변경하는 반면 -삭제 된 값없이 새 배열 (귀하에게 반환 됨)을 생성한다는 것입니다. 사용 사례에 따라 두 가지 접근 방식 중 하나가 적합 할 수 있습니다.
srt32

2
@ user3721428, delete (3)은 위치 3의 요소를 참조하지 않고 대신 정수 3과 일치하는 요소를 삭제합니다. 3의 모든 발생을 제거하며 배열 색인 또는 위치와 관련이 없습니다.
bkunzi01 2016 년

226

의견 에서 Travis 에서 빌린 경우 더 나은 답변입니다.

나는 개인적으로 같은 [1, 2, 7, 4, 5] - [7]에서 어떤 결과 => [1, 2, 4, 5]에서irb

3이 그의 예제 배열에서 세 번째 요소라는 것을 알면서 그의 대답을 수정했습니다. 이것은 3이 배열에서 2 위에 있다는 것을 모르는 사람들에게 혼란을 초래할 수 있습니다.


21
이 질문에 대해 알아 srt32 점으로 사용하는 사이에 만드는 중요한 차이있다 .delete-. .delete배열에서 제거 된 값을 반환합니다 (있는 경우). -하지 않을 것이다. 따라서 [ 1, 2, 3 ] - [ 2 ]돌아 오는 [ 1, 3 ]동안 [ 1, 2, 3 ].delete( 2 )돌아갑니다 2.
Argus9

5
array - subArrayArray of Arrays 에서는 작동하지 않지만 작동합니다 array.delete(subArray).
Sachin

21
사이의 중요한 차이점 [1,2,3] - [2][1,2,3].delete(2)그 인 delete방법 수정 원래 배열 하면서 [1,2,3] - [3]만들고 새로운 배열 .
티모시 코 발레 프

하위 어레이 다시 (위 Sachin의 코멘트 @) "물론이이 것"그냥 표기 권리를 얻을 필요가 : [1,2,[2],2,3,4] - [2]당신을 제공합니다 [1, [2], 3, 4],하지만 [1,2,[2],2,3,4] - [[2]]당신을 제공합니다 [1, 2, 2, 3, 4]. :-)
Tom Hundt

69

다른 옵션 :

a = [2,4,6,3,8]

a -= [3]

결과

=> [2, 4, 6, 8] 

50

누군가가 이것을 언급했는지 확실하지 않지만 Array.delete () 및-= value 는 Array 내에서 전달 된 값의 모든 인스턴스를 삭제합니다. 특정 요소의 첫 번째 인스턴스를 삭제하려면 다음과 같이 할 수 있습니다

arr = [1,3,2,44,5]
arr.delete_at(arr.index(44))

#=> [1,3,2,5]

더 간단한 방법이있을 수 있습니다. 나는 이것이 최선의 방법이라고 말하는 것이 아니라 인식해야 할 것입니다.


1
나는 이것을 할 수있는 방법을 찾고 있었고 중복 된 경우 요소의 인스턴스 하나만 삭제했으며 이것은 훌륭하게 작동합니다!
제로 쇼군

arr.index ()가 갈 수 있기 때문에이 대답이 잘못되었다고 생각합니다. nil
windmaomao

32

배열의 여러 위치에서 값으로 3을 삭제하려고한다고 가정하면이 작업을 수행하는 루비 방법은 delete_if 메소드를 사용하는 것입니다.

[2,4,6,3,8,3].delete_if {|x| x == 3 } 

'배열 배열'시나리오에서 요소를 제거 할 때 delete_if를 사용할 수도 있습니다.

이것이 귀하의 쿼리를 해결하기를 바랍니다.


25

나는 ~을 좋아한다 -=[4] 다른 답변에서 언급 된 방식이 값이 4 인 요소를 삭제하는 .

그러나이 방법이 있습니다 :

irb(main):419:0> [2,4,6,3,8,6].delete_if{|i|i==6}
=> [2, 4, 3, 8]
irb(main):420:0>

함수를 언급 한 후 " 기본 배열 연산 " 어딘가에 언급되었습니다 map.


그러나 당신은 그냥 사용할 수 없습니다.delete(6)
Zac

물론 @Zac하지만 이미 언급 된 그 대답 (매우 간결이 같은 -=방법 a-=[4]a=a-[4]. [3,4]-[4], 내가 좋아했다),하지만 난 또 다른 가능한 방법을 언급하고 싶었다.
barlop

이 메소드는 또한 삭제 된 요소 대신 배열을 리턴하는 이점이 있습니다.
F.Webber



15

벤치 마크는 다음과 같습니다.

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

그리고 다시 많은 중복을 포함하는 더 큰 배열이 있습니다.

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

그리고 더 많은 중복으로 더 큰 :

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

7
그렇다면 가장 좋은 것은 무엇입니까? :)
Kirby

8

Niels의 솔루션을 개선했습니다.

class Array          
  def except(*values)
    self - values
  end    
end

이제 사용할 수 있습니다

[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4)    # return [1, 2, 3]

irb콘솔에서 작동하지 않는 솔루션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

1
IRB에서 선언하려면 메소드를 Array에 추가해야합니다 class Array; def except(*values); self - values; end; end.
Mark Swardstrom

3

당신은 또한 원숭이 패치 할 수 있습니다. Ruby가 왜 except메소드를 가지고 있는지 이해 Hash하지 못했습니다 Array.

class Array
  def except value
    value = value.kind_of(Array) ? value : [value]
    self - value
  end
end

이제 할 수있는 일 :

[1,3,7,"436",354,nil].except(354) #=> [1,3,7,"436",nil]

또는:

[1,3,7,"436",354,nil].except([354, 1]) #=> [3,7,"436",nil]

1
value.kind_of(Array)시험이 필요 없습니다 . 그냥 사용하십시오 self - Array(value).
Sasgorilla

3

따라서 3이 여러 번 발생하고 3을 처음 만 삭제하려는 경우 다음과 같이 간단히 할 수 있습니다.

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.

3

첫 번째 발생의 비파괴 제거 :

a = [2, 4, 6, 3, 8]
n = a.index 3
a.take(n)+a.drop(n+1)

2

이 삭제 작업을 체인 가능하게 만들려면 일부 항목을 삭제하고 결과 배열에서 체인 작업을 계속하려면 tap다음을 사용하십시오 .

[2, 4, 6, 3, 8].tap { |ary| ary.delete(3) }.count #=> 4

1

루비에서 삭제에 대한 모든 다른 옵션을 컴파일

삭제 - 삭제가 값을 기준으로 요소를 일치. 둘 이상의 값이 일치하면 모두 제거됩니다. 발생 횟수에 신경 쓰지 않거나 단일 발생에 대해 확실하지 않은 경우이 방법을 사용하십시오.

a = [2, 6, 3, 5, 3, 7]
a.delete(3)  # returns 3
puts a       # return [2, 6, 5, 7]

delete_at- 주어진 색인에서 요소를 삭제합니다. 색인을 알고있는 경우이 방법을 사용하십시오.

# continuing from the above example
a.delete_at(2) # returns 5
puts a         # returns [2, 6, 7]

delete_if- 블록이 참인 모든 요소를 ​​삭제합니다. 배열이 수정됩니다. 블록이 호출되면 즉시 배열이 변경됩니다.

b = [1, 2, 5, 4, 9, 10, 11]
b.delete_if {|n| n >= 10}.  # returns [1, 2, 5, 4, 9]

거부 -주어진 블록이 거짓 인 요소를 가진 새로운 배열을 반환합니다. 이것으로 순서가 유지됩니다.

c = [1, 2, 5, 4, 9, 10, 11]
c.reject {|n| n >= 10}.  # returns [1, 2, 5, 4, 9]

받지 않다! -delete_if 와 동일 . 블록이 호출 될 때 배열이 즉시 변경되지 않을 수 있습니다.

배열에서 여러 값을 삭제하려면 가장 좋은 옵션은 다음과 같습니다.

a = [2, 3, 7, 4, 6, 21, 13]
b = [7, 21]
a = a - b    # a - [2, 3, 4, 6, 13]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.