免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 11701 | 回复: 10
打印 上一主题 下一主题

[练习] 合并行,并对值求和 [复制链接]

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-01 05:15 |只看该作者 |倒序浏览
问题 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

问题 2: 文件 size 有 50G 的时候, 如何 code?

论坛徽章:
31
CU大牛徽章
日期:2013-03-13 15:15:08CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-09-18 15:16:55CU大牛徽章
日期:2013-09-18 15:18:22CU大牛徽章
日期:2013-09-18 15:18:43CU十二周年纪念徽章
日期:2013-10-24 15:41:34丑牛
日期:2013-12-01 10:11:07水瓶座
日期:2014-01-15 08:47:25
2 [报告]
发表于 2014-01-18 23:58 |只看该作者
  1. #!/usr/bin/ruby -w

  2. aR=[]

  3. DATA.each_line.map(&:chomp).each do |a|
  4.   taR=a.split(/\s+/)
  5.   isOK = false
  6.   aR.each do |b|
  7.     if b[0]==taR[0] && b[1]==taR[1] && b[2]==taR[2] && b[3]==taR[3]
  8.       b[4] = b[4].to_i+taR[4].to_i
  9.       isOK = true;
  10.       #return
  11.     end

  12.   end

  13.   aR<<taR if isOK==false
  14. end

  15. aR.each {|x|
  16.   print x[0],?\t,x[1],?\t,x[2],?\t,x[3],?\t,x[4],?\n
  17. }

  18. __END__
  19. 1        20010201        100610        1.12        6000
  20. 1        20010201        100610        1.12        44000
  21. 1        20010201        100640        1.12        6000
  22. 2        20010201        100825        1.09        30000
  23. 2        20010201        100828        1.08        20000
  24. 2        20010201        100828        1.08        6000
  25. 1        20010202        100610        1.12        6000
  26. 1        20010202        100610        1.12        44000
  27. 2        20010202        100640        1.12        6000
  28. 3        20010202        100825        1.09        30000
  29. 3        20010202        100828        1.08        20000
  30. 3        20010202        100828        1.08        6000
复制代码
感觉写的好丑,还需要加强学习才行。
下次改进。

论坛徽章:
3
寅虎
日期:2013-11-27 07:53:29申猴
日期:2014-09-12 09:24:152015年迎新春徽章
日期:2015-03-04 09:48:31
3 [报告]
发表于 2014-01-19 09:32 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
31
CU大牛徽章
日期:2013-03-13 15:15:08CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-09-18 15:16:55CU大牛徽章
日期:2013-09-18 15:18:22CU大牛徽章
日期:2013-09-18 15:18:43CU十二周年纪念徽章
日期:2013-10-24 15:41:34丑牛
日期:2013-12-01 10:11:07水瓶座
日期:2014-01-15 08:47:25
4 [报告]
发表于 2014-01-19 09:42 |只看该作者
回复 3# Sevk


另外我发现我的代码有以下问题:
1,不需要chomp;
2,each中应该是直接返回,现在没有做;不知道怎么返回,求指教!!
3,我认为这段应该有更好的处理方式:
  1.     if b[0]==taR[0] && b[1]==taR[1] && b[2]==taR[2] && b[3]==taR[3]
  2.       b[4] = b[4].to_i+taR[4].to_i
  3.       isOK = true;
  4.       #return
  5.     end
复制代码
PS:我就是用的each_line,你的意思是read更好?

论坛徽章:
31
CU大牛徽章
日期:2013-03-13 15:15:08CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-09-18 15:16:55CU大牛徽章
日期:2013-09-18 15:18:22CU大牛徽章
日期:2013-09-18 15:18:43CU十二周年纪念徽章
日期:2013-10-24 15:41:34丑牛
日期:2013-12-01 10:11:07水瓶座
日期:2014-01-15 08:47:25
5 [报告]
发表于 2014-01-19 09:56 |只看该作者
下面代码修改了上个贴子说的三个问题,在第二个each中我发现break和next都能退出。
这儿有什么区别呢???
  1. #!/usr/bin/ruby -w

  2. aR=[]
  3. aI =0

  4. DATA.each_line do |a|
  5.   taR=a.split(/\s+/)
  6.   isOK = false
  7.   aR.each do |b|
  8.     if b[0]==taR[0] && b[1]==taR[1] && b[2]==taR[2] && b[3]==taR[3]
  9.       b[4] = b[4].to_i+taR[4].to_i
  10.       isOK = true;
  11.       #next
  12.       break
  13.     end
  14.     aI+=1

  15.   end

  16.   aR<<taR if isOK==false
  17. end

  18. aR.each {|x|
  19.   print x[0],?\t,x[1],?\t,x[2],?\t,x[3],?\t,x[4],?\n
  20. }
  21. puts aI

  22. __END__
  23. 1        20010201        100610        1.12        6000
  24. 1        20010201        100610        1.12        44000
  25. 1        20010201        100640        1.12        6000
  26. 2        20010201        100825        1.09        30000
  27. 2        20010201        100828        1.08        20000
  28. 2        20010201        100828        1.08        6000
  29. 1        20010202        100610        1.12        6000
  30. 1        20010202        100610        1.12        44000
  31. 2        20010202        100640        1.12        6000
  32. 3        20010202        100825        1.09        30000
  33. 3        20010202        100828        1.08        20000
  34. 3        20010202        100828        1.08        6000
复制代码

论坛徽章:
31
CU大牛徽章
日期:2013-03-13 15:15:08CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-09-18 15:16:55CU大牛徽章
日期:2013-09-18 15:18:22CU大牛徽章
日期:2013-09-18 15:18:43CU十二周年纪念徽章
日期:2013-10-24 15:41:34丑牛
日期:2013-12-01 10:11:07水瓶座
日期:2014-01-15 08:47:25
6 [报告]
发表于 2014-01-19 10:18 |只看该作者
在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本身就是一个循环。

论坛徽章:
31
CU大牛徽章
日期:2013-03-13 15:15:08CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-09-18 15:16:55CU大牛徽章
日期:2013-09-18 15:18:22CU大牛徽章
日期:2013-09-18 15:18:43CU十二周年纪念徽章
日期:2013-10-24 15:41:34丑牛
日期:2013-12-01 10:11:07水瓶座
日期:2014-01-15 08:47:25
7 [报告]
发表于 2014-01-19 12:41 |只看该作者
再改下:
  1. #!/usr/bin/ruby -w

  2. aR=[]

  3. DATA.each_line do |a|
  4.   taR=a.split(/\s+/)
  5.   isOK = false
  6.   aR.each do |b|
  7.     if b[0..3]==taR[0..3]
  8.       b[4] = b[4].to_i+taR[4].to_i
  9.       isOK = true
  10.       next
  11.     end
  12.   end

  13.   aR<<taR if isOK==false
  14. end

  15. aR.each { |x|
  16.   print x[0], ?\t, x[1], ?\t, x[2], ?\t, x[3], ?\t, x[4], ?\n
  17. }

  18. __END__
  19. 1        20010201        100610        1.12        6000
  20. 1        20010201        100610        1.12        44000
  21. 1        20010201        100640        1.12        6000
  22. 2        20010201        100825        1.09        30000
  23. 2        20010201        100828        1.08        20000
  24. 2        20010201        100828        1.08        6000
  25. 1        20010202        100610        1.12        6000
  26. 1        20010202        100610        1.12        44000
  27. 2        20010202        100640        1.12        6000
  28. 3        20010202        100825        1.09        30000
  29. 3        20010202        100828        1.08        20000
  30. 3        20010202        100828        1.08        6000
复制代码

论坛徽章:
3
寅虎
日期:2013-11-27 07:53:29申猴
日期:2014-09-12 09:24:152015年迎新春徽章
日期:2015-03-04 09:48:31
8 [报告]
发表于 2014-01-19 13:28 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
3
寅虎
日期:2013-11-27 07:53:29申猴
日期:2014-09-12 09:24:152015年迎新春徽章
日期:2015-03-04 09:48:31
9 [报告]
发表于 2014-01-19 13:29 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
10 [报告]
发表于 2014-01-22 01:15 |只看该作者
Sevk 发表于 2014-01-19 09:28
这里each比read好。read会把整个文件读入内存,如果有8G, 就把内存吃光了。

3 Q ~ ~ ~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP