合并行,并对值求和 的思考

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

原题目:

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


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值