美文网首页
ruby-inject/eval

ruby-inject/eval

作者: GALAXY_ZMY | 来源:发表于2015-09-20 23:25 被阅读71次

    最近用到数组求和比较频繁,了解了一下之前没怎么用过的inject
    数组求和
    Inject最常见的用法
    [1, 2, 3, 4, 5].inject(0) { |sum, e| sum + e }
    => 15
    或者
    (1..5).inject(0) { |sum, e| sum + e }
    => 15

    用区间或者数组在这里没有分别,Ruby会自动转换。Inject在这里接受一个方法参数和一个block. 对数组中的每一个元素,block都执行一次。第一次执行block的时候,inject接收的方法参数被作为block的第一个参数,而block的第二个参数则是数组的第一个元素。第二次执行block的时候,情况就有了变化,这也是inject神奇的地方。这时候block的第一个参数则是block上一次执行的返回值(block的最后一个表达式),第二个参数则是数组的第二个元素,后面的三次执行方式与第二次相同,这样我们就计算出了数组元素之和。事实上,上面的代码还可以更简洁一些:

    [1, 2, 3, 4, 5].inject { |sum, e| sum + e }
    => 15

    这段代码可以计算出相同结果的原因是:inject的方法参数是可选的,如果不提供的话,Ruby默认将数组的第一个元素作为block第一次执行时候的第一个参数,在这种情况下,block一共需要执行4次,比传入默认参数的形式少执行一次。

    转换数据结构
    生成Hash:
    hash = [[:first_name, 'Shane'], [:last_name, 'Harvie']].inject({}) do |result, element| result[element.first] = element.last
    result
    end

    当然这种用法也有别的形式,并不一定需要用到inject,比如:
    Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten]
    2.2 过滤数组:
    arr = [1, 2, 3, 4, 5, 6].inject([]) do |r, e|
    r << e.to_s if e % 2 == 0
    r
    end

    当然这种用法也有不使用inject的等价方式:
    [1, 2, 3, 4, 5, 6].select { |e| e % 2 == 0 }.collect { |e| e.to_s }
    => ["2", "4", "6"]

    (5..10).inject(1) { |product, n| product * n } #=> 151200

    longest = %w{ cat sheep bear }.inject do |memo, word| memo.length > word.length ? memo : word end longest #=> "sheep"
    求最长的字符串还可以用max方法
    a.max { |a, b| a.length <=> b.length } #=> "albatross"

    求和还有一个比较看上去更简单的方法eval
    eval [1,2,3,4].join('+')

    Ruby eval方法还可以动态执行字符串
    a = 1 b="true" c="false" str =" if a==1 then puts '输出:#{b}' else puts '输出:#{c}' end " eval(str) => 'true'

    相关文章

      网友评论

          本文标题:ruby-inject/eval

          本文链接:https://www.haomeiwen.com/subject/jrqicttx.html