Catch Ruby errors before your users do. Monitor Ruby production errors in real-time and debug them in minutes, before users notice. Our open source Ruby SDK works with Rails, Sinatra, and more. Use this link and get one month free!

RubyFlow The Ruby and Rails community linklog

×

The Ruby and Rails community linklog

Made a library? Written a blog post? Found a useful tutorial? Share it with the Ruby community here or just enjoy what everyone else has found!

Rails 6 adds Array#including, Array#excluding, Enumerable#including, Enumerable#exclu

Rails 6 adds Array#including, Array#excluding, Enumerable#including, Enumerable#excluding as more readable approaches to collection additions and removals.

https://blog.saeloun.com/2019/03/05/rails-6-array-including-excluding.html

Comments

I really like the idea but the implementation does exactly the opposite of what I thought it was made for, which is to avoid intermediary array creation.

Imagine this:

``` require ‘benchmark/ips’

module Enumerable def excluding(without) if without.kind_of?(Array) to_a.each { |item| yield item unless without.include?(item) } else to_a.each { |item| yield item unless item == without } end end

def including(with, &block) to_a.each(&block) if with.kind_of?(Array) with.each(&block) else yield with end end end

arr1 = Array.new(999_999) { ‘a’ * rand(20) } arr1.insert(500_000, ‘b’)

Benchmark.ips do |x| x.report(‘excluding’) { arr1.excluding(‘b’) { |a| a } } x.report(‘-‘) { (arr1 - [‘b’]).each { |a| a } } end

Benchmark.ips do |x| x.report(‘including’) { arr1.including(‘c’) { |a| a } } x.report(‘+’) { (arr1 + [‘c’]).each { |a| a } } end ```

The result:

Warming up -------------------------------------- excluding 1.000 i/100ms - 1.000 i/100ms Calculating ------------------------------------- excluding 11.487 (± 0.0%) i/s - 58.000 in 5.051945s - 11.567 (±17.3%) i/s - 57.000 in 5.067871s Warming up -------------------------------------- including 2.000 i/100ms + 1.000 i/100ms Calculating ------------------------------------- including 24.601 (± 0.0%) i/s - 124.000 in 5.041172s + 21.230 (±14.1%) i/s - 102.000 in 5.034892s

(you could also do: ([1,2,3,4].to_enum + [5].to_enum).each { |i| puts i })

Ok so this comment system doesn’t suport the three backticks syntax. Reposting:

I really like the idea but the implementation does exactly the opposite of what I thought it was made for, which is to avoid intermediary array creation.

Imagine this:

require 'benchmark/ips'

module Enumerable
  def excluding(without)
    if without.kind_of?(Array)
      to_a.each { |item| yield item unless without.include?(item) }
    else
      to_a.each { |item| yield item unless item == without }
    end
  end

  def including(with, &block)
    to_a.each(&block)
    if with.kind_of?(Array)
      with.each(&block)
    else
      yield with
    end
  end
end

arr1 = Array.new(999_999) { 'a' * rand(20) }
arr1.insert(500_000, 'b')

Benchmark.ips do |x|
  x.report('excluding') { arr1.excluding('b') { |a| a } }
  x.report('-') { (arr1 - ['b']).each { |a| a } }
end

Benchmark.ips do |x|
  x.report('including') { arr1.including('c') { |a| a } }
  x.report('+') { (arr1 + ['c']).each { |a| a } }
end

The result:

Warming up --------------------------------------
           excluding     1.000  i/100ms
                   -     1.000  i/100ms
Calculating -------------------------------------
           excluding     11.487  (± 0.0%) i/s -     58.000  in   5.051945s
                   -     11.567  (±17.3%) i/s -     57.000  in   5.067871s
Warming up --------------------------------------
           including     2.000  i/100ms
                   +     1.000  i/100ms
Calculating -------------------------------------
           including     24.601  (± 0.0%) i/s -    124.000  in   5.041172s
                   +     21.230  (±14.1%) i/s -    102.000  in   5.034892s

You could also do:

 ([1,2,3,4].to_enum + [5].to_enum).each { |i| puts i })

since enums support chaining nowadays.

Post a comment

You can use basic HTML markup (e.g. <a>) or Markdown.

As you are not logged in, you will be
directed via GitHub to signup or sign in