2010-07-30 214 views
2

我在LOOP1(CHECK1)嵌套循環2(CHECK2),但它似乎嵌套循環2(CHECK2)只運行一次。紅寶石嵌套循環

兩個循環都包含相同的數組。該腳本用於檢查check1中的重複ID。

check1=["0", "0", "0", "1", "1", "2", "3", "4", "5", "100", "4294967294", "9", "11", "6", "200", "7", "201", "811", "202", "204", "3000", "205", "3001", "3001", "3001"] 
check2 =["0", "0", "0", "1", "1", "2", "3", "4", "5", "100", "4294967294", "9", "11", "6", "200", "7", "201", "811", "202", "204", "3000", "205", "3001", "3001", "3001"] 

代碼:

check1.each do |check1| 
    counter=0 
    puts "checking against:"+check1.to_s 
    check2.each do |check2| 
    puts "checking:"+check1.to_s+"|"+check2.to_s 
    if check1 == check2 
     counter += 1 
    end 
    end 
    if counter > 1 
    dupUID << check1 
    end 
end 

結果:

checking against:0 <- checking the 1st element in check1 
checking:0|0 
checking:0|0 
checking:0|0 
checking:0|1 
checking:0|1 
checking:0|2 
checking:0|3 
checking:0|4 
checking:0|5 
checking:0|100 
checking:0|4294967294 
checking:0|9 
checking:0|11 
checking:0|6 
checking:0|200 
checking:0|7 
checking:0|201 
checking:0|811 
checking:0|202 
checking:0|204 
checking:0|3000 
checking:0|205 
checking:0|3001 
checking:0|3001 
checking:0|3001 
checking against:0<- checking the 2nd element in check1 
checking:0|3001 <- nested loop2(check2) is not looping again on the 2nd element of loop 1 
checking against:0 
checking:0|3001 <- loop2 stops at the last element for the remaining elements in check1 
checking against:1 
checking:1|3001 
checking against:1 
checking:1|3001 
checking against:2 
checking:2|3001 
checking against:3 
checking:3|3001 
checking against:4 
checking:4|3001 
checking against:5 
checking:5|3001 
checking against:100 
checking:100|3001 
checking against:4294967294 
checking:4294967294|3001 
checking against:9 
checking:9|3001 
checking against:11 
checking:11|3001 
checking against:6 
checking:6|3001 
checking against:200 
checking:200|3001 
checking against:7 
checking:7|3001 
checking against:201 
checking:201|3001 
checking against:811 
checking:811|3001 
checking against:202 
checking:202|3001 
checking against:204 
checking:204|3001 
checking against:3000 
checking:3000|3001 
checking against:205 
checking:205|3001 
checking against:3001 
checking:3001|3001 
checking against:3001 
checking:3001|3001 
checking against:3001 
checking:3001|3001 

任何人都可以指出我的錯誤?非常感謝。 解決:謝謝大家!

check1.each do |ch1| 
    counter=0 
    check2.each do |ch2| 
    if ch1 == ch2 
     counter += 1 
    end 
    end 
    if counter > 1 
    dupUID << ch1 
    end 
end 

puts dupUID 
+0

我認爲你的算法是有缺陷的。你爲什麼要比較兩個相同的陣列呢?即使使用你的方法,爲了找到重複,你需要檢查'counter> 1',而不是'counter> 0',因爲它們是相同的,因爲總是會有另一個數組中的1個匹配元素。如果你能解釋你在這裏做什麼,我相信有更好的方法來做到這一點。 – Anurag 2010-07-30 02:22:14

+0

他試圖在一個數組中找到重複的值。這個想法並不是那麼糟糕,執行會留下一些需要的東西。 – Amadan 2010-07-30 02:26:25

+0

嗨,Anurag是正確的,它應該是counter> 1.我需要在check1中找到重複的id。這意味着0,1,3001應該標記爲dupUID – cherhui 2010-07-30 02:31:22

回答

2

您陰影的check1check2陣列,因爲do塊變量具有相同的名稱作爲其中。

在內部do塊之後,check2引用數組的最後一個元素,而不是數組本身。

爲了解決這個問題,該塊變量重命名爲類似ch1ch2

因此,這解釋了爲什麼像您期望的嵌套循環沒有運行。其實,你的算法本身也有缺陷。 @floatless的答案提供了一個更好的方法來解決這個問題。

+0

謝謝!我犯了一個粗心的錯誤 – cherhui 2010-07-30 02:28:15

2

我想你不應該寫這樣的代碼。有一個更好的解決方案:

x = [0, 10, 15] 
y = [0, 20, 15] 
x & y # => [0, 15] 

此方法返回常見到指定的兩個數組元素。

(更新)還有另一種方法只有一個陣列內做到這一點:

[0, 10, 10, 15, 20].inject({}) 
{ 
    |a, c| a[c] ||= 0; a[c] = a[c].next; a 
}.delete_if { |k, v| v == 1 }.keys 
+0

嗨,對於誤解抱歉,我需要在check1中找到重複的ID。意思是0,1,3001應該被標記出dupUID – cherhui 2010-07-30 02:08:23

1

短,但沒有更多的可以理解的:

check.inject(Hash.new(0)) { |a, x| a[x] += 1; a }.reject { |k, v| v <= 1 }.keys 
0

假設你有一個單一的陣列check,你想要找到其中的所有重複的元素。使用Ruby 1.9。

check.group_by {|v| v}.map { |k, v| v.size > 1 ? k : nil }.compact 

說明:

  • group_by返回與鍵爲數字和值是每次出現時的陣列的散列。
  • map傳回零,如果發生的值只有一次,或者如果發生的值它不止一次。
  • compact清除所有nil值。

這裏是一步一步的結果:

# after group_by 
{"204"=>["204"], "6"=>["6"], "11"=>["11"], "205"=>["205"], "7"=>["7"], "811"=>["811"], "9"=>["9"], "4294967294"=>["4294967294"], "0"=>["0", "0", "0"], "100"=>["100"], "1"=>["1", "1"], "200"=>["200"], "2"=>["2"], "201"=>["201"], "3"=>["3"], "3000"=>["3000"], "202"=>["202"], "4"=>["4"], "3001"=>["3001", "3001", "3001"], "5"=>["5"]}> 

# after map 
[nil, nil, nil, nil, nil, nil, nil, nil, "0", nil, "1", nil, nil, nil, nil, nil, nil, nil, "3001", nil] 

# after compact 
["0", "1", "3001"] 
0

如果您對($VERBOSE = true)警告,它會通知你關於你有錯誤。

IRB對Ruby 1.9.1不允許你打開$ VERBOSE at the command line,但1.9.2會。

更新:這個問題導致我爲文件this bug/feature improvement的紅寶石。謝謝!