原题目:
http://bbs.chinaunix.net/thread-4113619-1-1.html
问题 1:
有一个文件,内容如下:
A B C D E
1 20010201 100610 1.12 6000
1 20010201 100610 1.12 44000
1 20010201 100640 1.12 6000
2 20010201 100825 1.09 30000
2 20010201 100828 1.08 20000
2 20010201 100828 1.08 6000
1 20010202 100610 1.12 6000
1 20010202 100610 1.12 44000
2 20010202 100640 1.12 6000
3 20010202 100825 1.09 30000
3 20010202 100828 1.08 20000
3 20010202 100828 1.08 6000
当某些行的A,B和C列同时匹配时,合并匹配行并把E列的值相加。
其他列的值保持不变。
预期结果是:
A B C D E
1 20010201 100610 1.12 50000
1 20010201 100640 1.12 6000
2 20010201 100825 1.09 30000
2 20010201 100828 1.08 26000
1 20010202 100610 1.12 50000
2 20010202 100640 1.12 6000
3 20010202 100825 1.09 30000
3 20010202 100828 1.08 26000
第一次写出代码如下:
#!/usr/bin/ruby -w
aR=[]
DATA.each_line.map(&:chomp).each do |a|
taR=a.split(/\s+/)
isOK = false
aR.each do |b|
if b[0]==taR[0] && b[1]==taR[1] && b[2]==taR[2] && b[3]==taR[3]
b[4] = b[4].to_i+taR[4].to_i
isOK = true;
#return
end
end
aR<<taR if isOK==false
end
aR.each {|x|
print x[0],?\t,x[1],?\t,x[2],?\t,x[3],?\t,x[4],?\n
}
__END__
1 20010201 100610 1.12 6000
1 20010201 100610 1.12 44000
1 20010201 100640 1.12 6000
2 20010201 100825 1.09 30000
2 20010201 100828 1.08 20000
2 20010201 100828 1.08 6000
1 20010202 100610 1.12 6000
1 20010202 100610 1.12 44000
2 20010202 100640 1.12 6000
3 20010202 100825 1.09 30000
3 20010202 100828 1.08 20000
3 20010202 100828 1.08 6000另外我发现我的代码有以下问题:
1,不需要chomp;
2,each中应该是直接返回,现在没有做;不知道怎么返回,求指教!!
3,我认为这段应该有更好的处理方式:
if b[0]==taR[0] && b[1]==taR[1] && b[2]==taR[2] && b[3]==taR[3]
b[4] = b[4].to_i+taR[4].to_i
isOK = true;
#return
end继续有疑问:
下面代码修改了上个贴子说的三个问题,在第二个each中我发现break和next都能退出。
这儿有什么区别呢???
答:
在Programming Ruby的358页中提到:
无论在那种block中,next语句将退出block,block的值就是传递给next的值,如果没有值传递给next,则为nil。
在raw proc中,break语句可以终止调用block的方法。方法的返回值为传递给break的参数。
在Programming Ruby的104页中提到:
break终止最接近的封闭循环体,然后执行block后面的语句。redo从循环头重新执行循环,但不重计算循环条件表达式或者获得迭代中的下一个元素。next跳到本次循环的末尾,并开始下一次迭代。
综上所述,我应该用next。break在第二个each中其作用其原因是,第二个each block本身就是一个循环。
再更新:
#!/usr/bin/ruby -w
aR=[]
DATA.each_line do |a|
taR=a.split(/\s+/)
isOK = false
aR.each do |b|
if b[0..3]==taR[0..3] #数组的比较,这么最简单。
b[4] = b[4].to_i+taR[4].to_i
isOK = true
next
end
end
aR<<taR if isOK==false
end
aR.each { |x|
print x[0], ?\t, x[1], ?\t, x[2], ?\t, x[3], ?\t, x[4], ?\n
}
__END__
1 20010201 100610 1.12 6000
1 20010201 100610 1.12 44000
1 20010201 100640 1.12 6000
2 20010201 100825 1.09 30000
2 20010201 100828 1.08 20000
2 20010201 100828 1.08 6000
1 20010202 100610 1.12 6000
1 20010202 100610 1.12 44000
2 20010202 100640 1.12 6000
3 20010202 100825 1.09 30000
3 20010202 100828 1.08 20000
3 20010202 100828 1.08 6000

本文介绍了一个使用Ruby语言处理数据合并的问题。通过对原始数据进行解析,实现了相同条件下的数据行合并及数值相加的功能。该文详细展示了Ruby代码的实现过程,并针对初版代码存在的问题进行了改进。
1202

被折叠的 条评论
为什么被折叠?



