Ruby语法糖:Enumerable方法inject/reduce

需求分析

并没有什么需求分析
依然是成绩订阅那个程序,自从我开始重构,我发现下面这个方法写的太恶心了,或者说,太java了。

课程名 成绩 考试时间
A 90 20150721
B 92 20150723
C 90 20150729
D 97 20150801
E 95 20160121
F 88 20160121
G 90 20160125
H 85 20160721
I 85 20160721
J 80 20160921
K 90 20160921

这是所有的考试成绩,以一个形如下面的Hash结构为元素,组成的一维数组

[
  { name: A, grade: 90, date: 20150721 },
  { name: B, grade: 92, date: 20150723 },
  { name: C, grade: 90, date: 20150729 }
]

由于我订阅成绩通常只需要知道当前学期,而且计算GPA也是分学期计算,所以我需要把这些数据按学期分开来。
通常情况下,同一学期的考试都是在同一天,但考虑到有些同学挂科补考的情况,我必须要考虑到各种客户的需求,有人问重修的怎么算?
算你麻痹 算新学期的考试。
所以我的任务是把这个一维数组,按照学期,变成一个二维数组,第一层是不同的学期,第二层是某学期的所有成绩列表。
我把5.1~11.1之间的考试都当做是第二学期,因为有开学补考嘛。所以算法思路是,通过判断是否为第二学期,如果是将flag置为true,如果不是则置为false,于是循环的时候,前几个都是true,然后到E科目的时候,就变成了false,所以这时候判定到了新学期,把这个下标记录下来,放到res数组里,如此遍历一遍,就可以把转折点的下标记录到一个数组里。

然后再根据res中每一个下标位置,用slice方法切割成绩数组,压入目标数组。
于是写出来了下面这个我后来都看不懂的代码。

def nest_with_date
  res = []
  z = 0
  second_semester = 500...1100
  flag = false
  @guide_score_list.each do |s|
    z += 1
    date = s[:date].slice(-4..-1).to_i
    res << (z - 1) unless flag == second_semester.include?(date)
    flag = second_semester.include?(date)
  end
  res << z
  res.length.times do |i|
    @score_list << @guide_score_list.slice((i.zero? ? 0 : res[i - 1])...res[i])
  end
end

Array#inject使用方法

于是我想到了最近看到的inject方法,就学习了一下姿势。
用法举例如下

list = [1,2,3,4]
result = list.inject(7) do |res, obj|
  res + obj
end
result # => 17

当inject加了参数,这个参数就是第一次迭代时res的初始值,此时res==7,obj==1,也就是第一个元素的值。
执行res+obj,返回值为8,这个8赋值给res,obj指向下一个元素,也就是2.
执行res+obj,返回值为10,这个10赋值给res,obj指向下一个...
以此类推
最后迭代完毕时res值就是整个方法的返回值,赋值给result变量就行了。
如果inject没有传参数,那么res的初始值就是list的第一个元素值——1,obj指向第二个元素值——2,然后同上

魔改重构

def nest_with_date
  # Magic rather than readable
  @score_list = @guide_score_list.inject([[@guide_score_list.first]]) do |res, s|
    next res if s == @guide_score_list.first
    l = (5_01...11_01).include?(res.last.last[:date].slice(-4..-1).to_i)
    n = (5_01...11_01).include?(s[:date].slice(-4..-1).to_i)
    l ^ n ? res << Array[s] : res.last << s
    res
  end
end

原本14行代码被我强行魔改成6行,注释里还要写上拒绝可读性...
这个算法的思路就更清晰了,实际上算法没什么变化,只是强行吃口语法糖。

我给res赋值了初始值,就是

[[{ name: A, grade: 90, date: 20150721 }]]

ln变量分别表示上一个成绩和当前这个成绩的日期是否在第二学期内
当这两个值相等时则表示在同一个学期,就把这个数据压入最后一个学期的第二层
当这两个值不等时则表示在不同的学期,要新开辟一个学期,所以把这个成绩包装成数组,压入第一层的尾部
l ^ n则表示异或关系,就不多说了。

这样目的就达到了。

人生苦短,我选Ruby~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 数组在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称...
    朱森阅读 3,890评论 2 13
  • Javascript有很多数组的方法,有的人有W3C的API,还可以去MDN上去找,但是我觉得API上说的不全,M...
    顽皮的雪狐七七阅读 4,062评论 0 6
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,771评论 1 10
  • 终于,今天建了一个自己的群——得到知识服务群 也终于,今天建了自己的微信公众号——杰牙青云得到知识服务 今天是20...
    牙医零柒阅读 406评论 0 0
  • 人与人之间存在很多情义,唯爱情最难琢磨、最曼妙,却也最恼人。 初尝恋爱。其实,说“爱”很没有底气,更多的是喜欢或好...
    Faaati阅读 326评论 0 1