2014-09-16 3 views
0

좋아, 누군가가 동적 크기 배열을 올바르게 반복하는 방법을 알려줄 수 있습니까? 은 여기의 의미는 다음과 같습니다조건부로 배열에 데이터 삽입

my_array = [1, 2, 3, 4, 2, 5, 15, 2] # <= there are three 2 inside my_array 

그런 다음 나는 "좋은"를 추가 할 때마다 반복은 여전히 ​​(정수 2, 나는, 여기에 내가 해봤 최선의 방법입니다 방법을 찾아 여러 가지 방법을 시도하지만하지 히트 반복 마지막 배열 (마지막 정수 2에 도달 할 수 있기 때문에 표시되지 있기 때문에

# First Method 
for i in 0..(my_array.length - 1) 
my_array.insert(i + 1, "good") if my_array[i] == 2 
end 

p my_array # => [1, 2, "good", 3, 4, 2, "good", 5, 15, 2] 

# Second Method 
for i in 0..(my_array.length - 1) 
my_array[i + 1] = "good" if my_array[i] == 2 
end 

p my_array # => [1, 2, "good", 4, 2, "good", 15, 2, "good"] 

첫 번째 방법은 없습니다 좋다) 내가 원하는 결과 "좋은"지난 2 후에, 나는)이 추측 "good"을 삽입 할 때마다 배열 크기가 커지므로 예상됩니다.

2 번마다 데이터를 "양호한"문자열로 바꿔주기 때문에 두 번째 것도 나쁘다.

p my_array # => [1, 2, "good", 3, 4, 2, "good", 5, 15, 2, "good"] 

모두 "좋은"데이터를 교체하지 않고 추가됩니다 지금 누군가가 내가 이런 식으로 생산할 수 있도록 내가 제대로이 일을 할 수있는 방법 나에게 지적 할 수 있습니다.

아무쪼록 고맙습니다. 정말 고마워요.

답변

3

당신은 더 나은 시간에 장소 수정하는 것보다 새로운 배열에 변형이있을 것이다 :

my_array = [1, 2, 3, 4, 2, 5, 15, 2] 

def add_good(a) 
    a.flat_map do |value| 
    case (value) 
    when 2 
     [ 2, 'good' ] 
    else 
     value 
    end 
    end 
end 

puts add_good(my_array).inspect 
# => [1, 2, "good", 3, 4, 2, "good", 5, 15, 2, "good"] 

flat_map 방법을 사용하여 결과 배열에 0 개 이상의 항목을 만들려는 경우에 유용합니다 . map은 1 : 1 매핑이고, flat_map은 1 : N입니다.

이것이 훨씬 더 일반적인 만들 수도 있습니다 : 당신이 임의의 블록과 가치를 전달할 수

def fancy_insert(a, insert) 
    a.flat_map do |value| 
    if (yield(value)) 
     [ value, insert ] 
    else 
     value 
    end 
    end 
end 

result = fancy_insert(my_array, 'good') do |value| 
    value == 2 
end 

puts result.inspect 

그런 식으로 삽입 할 수 있습니다. .each_with_index 방법을 사용하지 않는 이유는

+0

'value == 2? [2, 'good'] : value'는 블록에 대해 수행합니다. –

+0

교육적 예를 위해 나는 가능한 한 논리를 명확하게하려고 노력한다. 삼항 연산자는 다소 혼란 스러울 수 있으며, 추가 사례를 추가 할 때 매우 잘 정의되지 않습니다. – tadman

+0

충분합니다. 여전히,'case' 문의'else' 브랜치에 추가 배열을 생성 할 필요는 없습니다. –

2

:

arr = [1, 2, 3, 4, 5, 2, 3, 5] 
arr.each_with_index {|e, i| arr.insert(i+1, "good") if e == 2} 

빠른 속도와 분노.

+0

와우 덕분에 문제를 해결하는 데 도움이됩니다.고맙습니다 =) – LuminaChen

+0

다른 사람이 사용할 수 있도록 솔루션으로 표시하는 것을 잊지 마세요. :) – tebayoso

0

는 여기에 열거를 사용하여, 당신이 그것을 할 수있는 또 다른 방법 : 열거가 마지막 요소에 이미 때

my_array = [1, 2, 3, 4, 2, 5, 15, 2] 

enum = my_array.each 
    #=> #<Enumerator: [1, 2, 3, 4, 2, 5, 15, 2]:each> 

my_array = [] 
loop do 
    x = enum.next 
    my_array << x 
    my_array << "good" if x == 2 
end 
my_array 
    #=> [1, 2, "good", 3, 4, 2, "good", 5, 15, 2, "good"] 

Enumerator#nextStopInteration 예외를 발생시킵니다. Kernel#loop은 루프를 끊음으로써 예외를 처리합니다. 따라서 열거자를 단계별로 실행할 때 loop이 자주 사용됩니다.