2009-09-17 5 views
0

Ruby에 배열이 있습니다. 인덱스 속성을 기반으로하는 Ruby 배열 조작

  1. 배열에서의 위치에 따라 요소의 하위 집합을 가져 오기 - 모든 5 요소를 말한다 : 내가 원하는. each_index를 사용하여이 작업을 수행하거나 select_with_index 메서드를 확장하여 만들 수 있습니다.

  2. 이 전체 하위 집합에 종속적 인 일부 작업을 수행 - subset.map {| 요소 | subset.sum - 요소}

  3. 이 내가에 붙어 비트는 다음과 같습니다 2 단계 예에 항목으로 대체 올바른 항목 새로운 배열 만들기 : 그래서

을 내 매우 복잡한 예 : 가질 수 있습니다 :

Start: [3,0,6,11,77,2,1,5,48,9,122,0,43,13,564] 

Select: [3,2,122] 

Map:  [124,125,5] 

Replace: [124,0,6,11,77,125,1,5,48,9,5,0,43,13,564] 

어떻게 우아한 방식으로 교체를 수행 할 수 있습니까? 두 배열을 결합하여 블록 {| i |를 사용하는 방법을 만드는 방법이 있습니까? i % 5 == 0}?

EDIT (이 좀 더 루비를 ... 배우기 위해 소형 스도쿠 솔버를 작성하는 접근 방식에 의해 좌우됩니다) : 예제 값을 변경했습니다. 희망적으로 이것은 지금 더 명확하다.

+0

음과 함께이 문제를 해결 것, (: 여기

그것의 좀 더 컴팩트 한 버전입니다 3 + 2 + 122) -122 = 6 –

+0

D' oh. 변명하지. –

답변

0

하위 집합의 길이를 알 필요가없는 경우 한 번에 할 수 있습니다.

a = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] 
p a.map {|i| i % 5 == 0 ? "foo" : i } 
# => ["foo", 1, 2, 3, 4, "foo", 6, 7, 8, 9, "foo", 11, 12, 13, 14, "foo"] 

당신과 같이 두 개의 패스를 할 수있는, 당신은 Array#sum 다른 곳에서 구현 한 가정 :

a = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] 
sum = a.select {|i| i % 5 == 0 }.sum 
p a.map {|i| i % 5 == 0 ? sum - i : i } 
# => [30, 1, 2, 3, 4, 25, 6, 7, 8, 9, 20, 11, 12, 13, 14, 15] 
+0

요소가 색인과 일치하므로 예제가 혼동 스러울 수 있습니다. 내가 바꾸면 더 분명해질거야. 사과. –

+0

accumulator를 사용하면'sum'은 거의 내장되어 있습니다 :'arr.inject (& : +)' – samuil

1

은 합계 방법을 가정한다 레일의 하나는,이 작동 될 수 있습니다

a = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] 
b = [] 
a.each_index {|i| b[i] = a[i] if i%5 == 0} 
c = b.map{|p| p.nil? ? nil : b.sum{|i| i.nil? ? 0 : i} - p} 
c.each_index {|i| a[i] = c[i] unless c[i].nil?} 

리팩터링을 통해 유용하게 활용할 수 있습니다. 기본적으로 이론은 원래 배열의 모든 인덱스를 하위 집합으로 유지하는 것입니다. 그렇게하면 나중에 교체 할 애셋을 쉽게 알 수 있습니다. 더 복잡한 계산이있는 경우 해시를 사용할 수도 있습니다.

a = [3,0,6,11,77,2,1,5,48,9,122,0,43,13,564] 
b = [] 

a.each_index {|i| b[i] = a[i] if i%5 == 0} 
b.each_with_index {|obj, i| 
    a[i] = b.inject(0){|m,v| v.nil? ? m : v} - obj unless obj.nil?} 
+0

예, 가능합니다. sum 메쏘드는 실제로 만들어졌습니다. inject (0) {| s, i | s + = i i.nil 않는 한?} ... –

+0

주사를 맞히고 싶지 않다고 생각하지 않습니다. inject (0) {| m, i | 나? ? m : m + i} 더 좋을 것입니다. 그리고 네. 기본적으로 Rails가 수행하는 방식입니다. 그러나 nil 검사는 제외합니다. –

+0

동의 - 코드를 테스트하지 않았습니다. –

2
a = [3, 0, 6, 11, 77, 2, 1, 5, 48, 9, 122, 0, 43, 13, 564] 

# per your requirements 
def replace_indices(ary, &index_selector) 
    indices = ary.each_index.select(&index_selector) 
    sum = indices.inject(0) {|sum, i| sum += ary[i]} 
    indices.each {|i| ary[i] = sum - ary[i]} 
    ary 
end 

p new = replace_indices(a.dup) {|i| i % 5 == 0} 

# just pass the "index step value" 
def replace_each_step(ary, step) 
    sum = 0 
    ary.each_index . 
     select {|i| i % step == 0} . 
     collect {|i| sum += ary[i]; ary[i]} . 
     each_with_index {|e,i| ary[i*step] = sum - e} 
    ary 
end 

p new = replace_each_step(a.dup, 5) 
1

나는 아마 Enumerable#enum_for(:each_with_index)

require 'enumerator' 

values = [3,0,6,11,77,2,1,5,48,9,122,0,43,13,564] 

subset_with_indexes = values.enum_for(:each_with_index).select { |v,i| i % 5 == 0 } 
#=> [ [3,0], [2,5], [122,10] ] 

subset_sum = subset_with_indexes.inject(0) { |s,(v,i)| s+v } 
#=> 127 

subset_with_indexes.each do |v,i| 
    values[i] = subset_sum - v 
end 

values #=> [124, 0, 6, 11, 77, 125, 1, 5, 48, 9, 5, 0, 43, 13, 564] 

또는

require 'enumerator' 

values = [3,0,6,11,77,2,1,5,48,9,122,0,43,13,564] 
values_with_indexes = values.enum_for(:each_with_index) 

subset_sum = values_with_indexes.inject do |s,(v,i)| 
    i % 5 == 0 ? s + v : s 
end #=> 127 

new_values = values_with_indexes.map do |v,i| 
    i % 5 == 0 ? subset_sum - v : v 
end #=> [124, 0, 6, 11, 77, 125, 1, 5, 48, 9, 5, 0, 43, 13, 564]