How to map and remove nil values in Ruby

前端 未结 8 1592
野性不改
野性不改 2020-12-07 07:51

I have a map which either changes a value or sets it to nil. I then want to remove the nil entries from the list. The list doesn\'t need to be kept.

Thi

8条回答
  •  时光说笑
    2020-12-07 08:14

    Ruby 2.7+

    There is now!

    Ruby 2.7 is introducing filter_map for this exact purpose. It's idiomatic and performant, and I'd expect it to become the norm very soon.

    For example:

    numbers = [1, 2, 5, 8, 10, 13]
    enum.filter_map { |i| i * 2 if i.even? }
    # => [4, 16, 20]
    

    In your case, as the block evaluates to falsey, simply:

    items.filter_map { |x| process_x url }
    

    "Ruby 2.7 adds Enumerable#filter_map" is a good read on the subject, with some performance benchmarks against some of the earlier approaches to this problem:

    N = 100_000
    enum = 1.upto(1_000)
    Benchmark.bmbm do |x|
      x.report("select + map")  { N.times { enum.select { |i| i.even? }.map{ |i| i + 1 } } }
      x.report("map + compact") { N.times { enum.map { |i| i + 1 if i.even? }.compact } }
      x.report("filter_map")    { N.times { enum.filter_map { |i| i + 1 if i.even? } } }
    end
    
    # Rehearsal -------------------------------------------------
    # select + map    8.569651   0.051319   8.620970 (  8.632449)
    # map + compact   7.392666   0.133964   7.526630 (  7.538013)
    # filter_map      6.923772   0.022314   6.946086 (  6.956135)
    # --------------------------------------- total: 23.093686sec
    # 
    #                     user     system      total        real
    # select + map    8.550637   0.033190   8.583827 (  8.597627)
    # map + compact   7.263667   0.131180   7.394847 (  7.405570)
    # filter_map      6.761388   0.018223   6.779611 (  6.790559)
    

提交回复
热议问题