2010-07-30 159 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的红宝石。谢谢!