• ruby reduce方法


    Ruby 中一些好用的方法(注意reduce方法)

    #####inject

    inject是我使用最频繁的方法了,它的强大之处在于可以方便的对嵌套的数组,哈希等混合数据结构进行合并或求和, 可以有效减少代码量。

    例如最常见的数组套哈希:

    1
    2
    3
    4
    array = [{a:100}, {b:200}, {c:300}]
    
    array.inject(0) { |sum, e| sum += e.values.first } #600
    array.inject({}) { |sum, e| sum.merge e } #{:a=>100, :b=>200, :c=>300}
    • inject():括号中的是sum的初始值
    • sum, e: 和在前,数组元素在后,中间必须以逗号隔开

    #####group_by

    group_by适用于对于数组和hash的分组. 在stackoverflow,我经常遇到这样的问题:

    array根据相同的school_id进行分组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    array =  [{"school_id"=>"1",
    		  "plan_type"=>"All",
    		  "view"=>"true",
    		  "create"=>"true",
    		  "approve"=>"true",
    		  "grant"=>"true",
    		  "region_id"=>nil},
    		 {"school_id"=>"1",
    		  "plan_type"=>"All",
    		   "edit"=>"true",
    		   "region_id"=>nil},
    		 {"school_id"=>"2",
    		  "plan_type"=>"All",
    		  "edit"=>"true",
    		  "grant"=>"true",
    		  "region_id"=>nil}]
    
    array.group_by { |e| e["school_id"] }
    => {"1"=>[{"school_id"=>"1", "plan_type"=>"All", "view"=>"true", "create"=>"true", "approve"=>"true", "grant"=>"true", "region_id"=>nil}, {"school_id"=>"1", "plan_type"=>"All", "edit"=>"true", "region_id"=>nil}], "2"=>[{"school_id"=>"2", "plan_type"=>"All", "edit"=>"true", "grant"=>"true", "region_id"=>nil}]}

    多条件分组:

    1
    2
    array.group_by { |e| [e["school_id"], e["plan_type"]] } #将多个条件放在数组当中
    => {["1", "All"]=>[{"school_id"=>"1", "plan_type"=>"All", "view"=>"true", "create"=>"true", "approve"=>"true", "grant"=>"true", "region_id"=>nil}, {"school_id"=>"1", "plan_type"=>"All", "edit"=>"true", "region_id"=>nil}], ["2", "All"]=>[{"school_id"=>"2", "plan_type"=>"All", "edit"=>"true", "grant"=>"true", "region_id"=>nil}]}

    ####reduce

    reduce作用和inject优点类似,但是它比inject还要简洁

    1
    2
    3
    (5..10).inject {|sum, n| sum + n }  # 45
    (5..10).reduce(:+)  # 45
    (5..10).reduce(1, :+)  # 46 (括号中第一个参数是初始值,第二个是方法名)

    group_by中的array为例,将相同school_id的hash进行合并

    1
    2
    array.group_by { |e| e["school_id"] }.values.map { |i| i.inject({}) { |sum ,e| sum.merge e }}
    => [{"school_id"=>"1", "plan_type"=>"All", "view"=>"true", "create"=>"true", "approve"=>"true", "grant"=>"true", "region_id"=>nil, "edit"=>"true"}, {"school_id"=>"2", "plan_type"=>"All", "edit"=>"true", "grant"=>"true", "region_id"=>nil}]

    可以使用inject将hash合并,但是使用reduce效果会更好

    1
    2
    array.group_by { |e| e["school_id"] }.values.map { |i| i.reduce(:merge) }
    => [{"school_id"=>"1", "plan_type"=>"All", "view"=>"true", "create"=>"true", "approve"=>"true", "grant"=>"true", "region_id"=>nil, "edit"=>"true"}, {"school_id"=>"2", "plan_type"=>"All", "edit"=>"true", "grant"=>"true", "region_id"=>nil}]

    ####zip

    zip可以将两个数组合并为一个二维数组

    1
    2
    3
    4
    a= [1,2,3,4,5]
    b=[6,7,8,9,10]
    a.zip(b)
    => [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

    如果a.length > b.length,b中缺少的以nil代替 ,

    1
    2
    3
    4
    a=[1,2,3,4,5,6]
    b=[6,7,8,9,10]
    a.zip(b)
    => [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10], [6, nil]]

    如果a.length < b.length,b中多余的直接被丢弃

    1
    2
    3
    4
    a= [1,2,3,4]
    b=[6,7,8,9,10]
    a.zip(b)
    => [[1, 6], [2, 7], [3, 8], [4, 9]]
     
     
     
     
  • 相关阅读:
    hdu 1695(莫比乌斯反演)
    hdu 6035(Colorful Tree)
    Splay模板(序列终结者)
    我的CSDN博客
    【洛谷P2041 分裂游戏】数学+瞎蒙
    【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导
    【LOJ 109 并查集】 并查集
    【洛谷P1816 忠诚】线段树
    【洛谷1339 [USACO09OCT]】热浪Heat Wave 图论+最短路
    【洛谷1433】吃奶酪 搜索+剪枝
  • 原文地址:https://www.cnblogs.com/tabCtrlShift/p/6576373.html
Copyright © 2020-2023  润新知