Skip to content

Instantly share code, notes, and snippets.

@HarlemSquirrel
Last active February 2, 2017 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarlemSquirrel/64bde56c98a1130750486f09a3a6e21e to your computer and use it in GitHub Desktop.
Save HarlemSquirrel/64bde56c98a1130750486f09a3a6e21e to your computer and use it in GitHub Desktop.
Flattener with Benchmarking
class Flattener
def initialize(nested_array)
@nested_array = nested_array
end
def call
@flattened_array = []
flatten nested_array
flattened_array
end
private
attr_reader :flattened_array, :nested_array
def flatten(array)
array.each { |i| i.is_a?(Array) ? flatten(i) : flattened_array << i }
end
end
#!/usr/bin/env ruby
require 'benchmark'
require_relative 'flattener'
# Adapted from Mike's post
# http://adayinthepit.com/2011/07/27/two-variations-on-ruby-arrayflatten/
def jons_flatten values, level=-1
flat = []
values.each do |value|
if level != 0 && value.kind_of?(Array)
flat.concat(jons_flatten(value, level-1))
else
flat << value
end
end
flat
end
def mikes_flatten arr, level = nil
result = []
arr.each do |elem|
recursive_flatten(result, elem,level,0)
end
result
end
def recursive_flatten(result, elem,level,current_level)
if elem.is_a?(Array)
elem.each do |el|
if level.nil? || current_level < level
recursive_flatten(result, el,level,current_level+1)
else
result << el
end
end
else
result << elem
end
result
end
def random_value
if rand(3) < 1
(rand(5)+1).times.map { |i| random_value }
else
rand(10000)
end
end
VALUE = 100.times.map { |i| random_value}
ITERATIONS = 1000
Benchmark.bm do |b|
puts "Iterations: #{ITERATIONS}"
b.report("Ruby Array#flatten") do
ITERATIONS.times { |i| VALUE.flatten}
end
b.report("Jon's version") do
ITERATIONS.times { |i| jons_flatten(VALUE)}
end
b.report("Mike's version") do
ITERATIONS.times { |i| mikes_flatten(VALUE)}
end
b.report("My version") do
ITERATIONS.times { |i| Flattener.new(VALUE).call }
end
end
require_relative '../flattener'
RSpec.describe Flattener do
let(:flattener) { described_class.new nested_array }
describe '#call' do
context "with a small nested array" do
let(:flattened_array) { [1,2,3,4] }
let(:nested_array) { [[1,2,[3]],4] }
it 'flattens nested arrays' do
expect(flattener.call).to eq flattened_array
end
end
context "with a large nested array" do
let(:flattened_array) { %w(a b c d e f g) }
let(:nested_array) { ["a", ["b", "c", ["d", [[["e"]]]]], "f", [["g"]]] }
it 'flattens nested arrays' do
expect(flattener.call).to eq flattened_array
end
end
end
end
@HarlemSquirrel
Copy link
Author

Benchmark for my Flattener

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment