December 12, 2015 by Daniel P. Clark

Ruby: Arrays by Example

Arrays are Ruby’s most used collection type.  I will use very little description as I give examples for the many different ways to work with Arrays.

Different ways to create an empty Array
[]
Array.new
Array[] # same as :new
Array(nil) # tries converting to an Array first and insures an Array result

%w^^ # you can use any character pair-up after the w.  content won't need quotes
%W^^ # Allows string interpolation
Filling an Array
laughing_pirate = Array.new(3, :arr)
# => [:arr, :arr, :arr]

[42] * 5
# => [42, 42, 42, 42, 42]

[1,2,3].insert(10,8) # position, item ## fills beyond with nil
# => [1, 2, 3, nil, nil, nil, nil, nil, nil, nil, 8]

x = [1,2,3]
x[9] = 10 # just like insert
# => [1, 2, 3, nil, nil, nil, nil, nil, nil, 10]
Insertion
[1,2,3,4,5,6].insert 4, :hello
# => [1, 2, 3, 4, :hello, 5, 6]

x = [1,2,3,4,5,6,7,8]
x[2,4] = :hello # slice replacement
x
# => [1, 2, :hello, 7, 8]

x[2,2] = [3,4,5,6] # slice replacement
x
# => [1, 2, 3, 4, 5, 6, 8]

x[2] = [8,7] # creates inner array
x
# => [1, 2, [8, 7], 4, 5, 6, 8]

x[1..4] = [7] # range slice insertion
x
# => [1, 7, 6, 8]
Boolean/Truthiness
[false, false, false].all?
# => false 

[true, false, false].all?
# => false 

[true, true, true].all?
# => true

[false, false, false].any?
# => false 

[false, true, false].any?
# => true

[1,2,3,4].all?(&:even?)
# => false

[1,2,3,4].any?(&:even?)
# => true

[1,2,3,4].any? {|item| item > 2 && item < 4}
# => true

[1,2,3,4].one?
# => false 

[4].one?
# => true

[1,2,3,4].one?(&:even?)
# => false

[1,2,3].one?(&:even?)
# => true

[1,2,3].empty?
# => false 

[].empty?
# => true

[1,2,3].include? 5
# => false

[1,2,3].frozen?
# => false

[1,2,3].eql? [1,2]
# => false

[1,2,3].== [1,2]
# => false
Transformations
# zip
['H', 'l', 'o', 'o', 'l'].zip( ['e', 'l', 'W', 'r', 'd'] )
# => [["H", "e"], ["l", "l"], ["o", "W"], ["o", "r"], ["l", "d"]]

# transpose
[["H", "e"], ["l", "l"], ["o", "W"], ["o", "r"], ["l", "d"]].transpose
# => [["H", "l", "o", "o", "l"], ["e", "l", "W", "r", "d"]]

# product
[:a,:b,:c].product [1,2,3]
# => [[:a, 1], [:a, 2], [:a, 3], [:b, 1], [:b, 2], [:b, 3], [:c, 1], [:c, 2], [:c, 3]]

# combination (no repetitions of pairings)
[:a,:b,:c,:d].combination(2).to_a
# => [[:a, :b], [:a, :c], [:a, :d], [:b, :c], [:b, :d], [:c, :d]]

# permutation (will give both [a,b] and [b,a])
[:a,:b,:c].permutation(2).to_a
# => [[:a, :b], [:a, :c], [:b, :a], [:b, :c], [:c, :a], [:c, :b]]

# reverse and reverse!
[1,2,3].reverse
# => [3, 2, 1]

# sort and sort!
[2,1,3].sort
# => [1, 2, 3]

# shuffle and shuffle!
[1,2,3].shuffle
# => [3, 1, 2]

# uniq and uniq!
[2,1,3,3,1,2].uniq
# => [2, 1, 3]

# rotate and rotate!
[:a,:b,:c].rotate
# => [:b, :c, :a]

# compact and compact!
[:a,:b,nil,nil,nil,:c].compact
# => [:a, :b, :c]

# flatten and flatten!
[["H", "e"], ["l", "l"], ["o", "W"], ["o", "r"], ["l", "d"]].flatten
# => ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"]
Slicing
# slice and slice!
[1,2,3,4,5,6,7,8].slice(2)
# => 3 

[1,2,3,4,5,6,7,8][2]
# => 3 

[1,2,3,4,5,6,7,8].slice(2..5)
# => [3, 4, 5, 6] 

[1,2,3,4,5,6,7,8][2..5]
# => [3, 4, 5, 6] 

[1,2,3,4,5,6,7,8].slice(2,5)
# => [3, 4, 5, 6, 7]

[1,2,3,4,5,6,7,8][2,5]
# => [3, 4, 5, 6, 7]

# Enumerables
[8,7,6,5,4,3,2,1].slice_after(2).to_a
# => [[8, 7, 6, 5, 4, 3, 2], [1]]
 
[8,7,6,5,4,3,2,1].slice_before(2).to_a
# => [[8, 7, 6, 5, 4, 3], [2, 1]]

[1,2,4,9,10,11,12,15,16,19,20,21].slice_when {|i,j| i+1 != j}.to_a
# => [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]
Adding
[2,3,4] + [5,6,7]
# => [2, 3, 4, 5, 6, 7] 

[2,3,4] << [5,6,7]
# => [2, 3, 4, [5, 6, 7]]

[2,3,4] .concat [5,6,7]
# => [2, 3, 4, 5, 6, 7] 

[2,3,4] .unshift [5,6,7]
# => [[5, 6, 7], 2, 3, 4]

[2,3,4] .push [5,6,7]
# => [2, 3, 4, [5, 6, 7]]

[2,3,4] | [3,4,5,6,7]
# => [2, 3, 4, 5, 6, 7]
Replace & Remove
[2,3,4] .replace [4,5,6]
# => [4, 5, 6]

x = [1,2,3,4,5]
x.pop
# => 5 
x
# => [1, 2, 3, 4] 

x.shift
# => 1 
x
# => [2, 3, 4]

x.clear
# => []

x = [1,2,3,4,5]
x.delete(2)
# => 2 
x
# => [1, 3, 4, 5] 

x.delete_at(3)
# => 5 
x
# => [1, 3, 4] 

[1,2,3,4,5,6,7,8].delete_if(&:even?)
# => [1, 3, 5, 7]

[1,2,3,4,5,6,7,8].delete_if {|n| n.even? && n > 4}
# => [1, 2, 3, 4, 5, 7]

[1,2,3,4,5,6,7,8].keep_if(&:odd?)
# => [1, 3, 5, 7]

[:a,:b,:c,:d,:e] - [:a,:e]
# => [:b, :c, :d]
Selecting
# Already covered are keep_if, delete_if, slice, []

[1,2,3,4,5,6,7,8].select(&:even?)
# => [2, 4, 6, 8]

[1,2,3,4,5,6,7,8].select {|n| n < 3 || n > 5}
# => [1, 2, 6, 7, 8]

[1,2,3,4,5,6,7,8].detect(&:even?) # Detect gets first truth result
# => 2

[1,2,3,4,5,6,7,8].values_at(2)
# => [3] 

[1,2,3,4,5,6,7,8].values_at(2,4)
# => [3, 5] 

[1,2,3,4,5,6,7,8].values_at(2,4,5)
# => [3, 5, 6] 

[1,2,3,4,5,6,7,8].values_at(2..5)
# => [3, 4, 5, 6]

# reject and reject!
[1,2,3,4,5,6,7,8].reject(&:even?)
# => [1, 3, 5, 7]

[1,2,3,4,5,6,7,8].find {|i| i.even?}
# => 2

[1,2,3,4,6,8,9,11,13,14,15,16].chunk(&:even?).to_a
# => [[false, [1]], [true, [2]], [false, [3]], [true, [4, 6, 8]], [false, [9, 11, 13]], [true, [14]], [false, [15]], [true, [16]]]

[1,2,3,4,5,6,7,8].take(3)
# => [1, 2, 3]

[1,2,3,4,5,6,7,8].group_by(&:even?)
# => {false=>[1, 3, 5, 7], true=>[2, 4, 6, 8]}

[2,3,4] .partition {|i| i.even?}.to_a
# => [[2, 4], [3]]

[0,1,2,3,4,5,6,7,9].group_by.with_index {|_,index| index % 4 }.values
# => [[0, 4, 9], [1, 5], [2, 6], [3, 7]]
Mapping
[1,2,3,4,5,6,7,8].map {|n| n.even? ? n*4 : [n]}
# => [[1], 8, [3], 16, [5], 24, [7], 32] 

[1,2,3,4,5,6,7,8].flat_map {|n| n.even? ? n*4 : [n]}
# => [1, 8, 3, 16, 5, 24, 7, 32]

[1,2,3,4,5,6,7,8].collect_concat {|n| n.even? ? n*4 : [n]}
# => [1, 8, 3, 16, 5, 24, 7, 32]
Reduce with compounded result
[1,2,3,4,5,6,7,8].reduce(:+)
# => 36 

[1,2,3,4,5,6,7,8].inject(:+)
# => 36 

[1,2,3,4,5,6,7,8].inject(:*)
# => 40320

x.reduce({}) {|hash, a| hash[a.even?] = Array(hash[a.even?]) << a ; hash}
# => {false=>[1, 3, 5, 7], true=>[2, 4, 6, 8]}

x.inject({}) {|hash, a| hash[a.even?] = Array(hash[a.even?]) << a ; hash}
# => {false=>[1, 3, 5, 7], true=>[2, 4, 6, 8]}
Counting
[1,2,3,4,5].count
# => 5 

[1,2,3,4,5].count(&:odd?)
# => 3 

["Ah","Ac","2c"].count {|c| c[0] == "A"}
# => 2
Array()
class Example
  def to_ary
    puts "to_ary called"
    []
  end
  def to_a
    puts "to_a called"
    []
  end
end

Array(Example.new)
#to_ary called
# => []

class Example
  undef :to_ary
end

Array(Example.new)
#to_a called
# => [] 

class Example
  undef :to_a
end

Array(Example.new)
# => [#<Example:0x00000000a72880>]

As you can see Array() tries to call to_ary first, to_a if that doesn’t work, and just wraps the object in an Array if neither of those methods are defined.

The Ws
cow = "moo"

%w^ 1 2 3 #{cow} 4 5 6^
# => ["1", "2", "3", "\#{cow}", "4", "5", "6"]

%W^ 1 2 3 #{cow} 4 5 6^
# => ["1", "2", "3", "moo", "4", "5", "6"]

%w[]
# => []

%w{}
# => []

%w()
# => []

%W("a" 'b' c' "d)
# => ["\"a\"", "'b'", "c'", "\"d"]

As you can see the Ws are great if you want to have either kind of quotation marks within your string items.

In closing

In all of the examples above I’ve shown the output but haven’t explicitly revealed whether the methods change the Array they’re called on or just return an Array result.  Please experiment for yourself in an irb terminal to find out more.  Typically any method ending with an exclamation point (!) changes the Array itself.

Feel free to check out my other related posts on Different Collection Types in RubyWhen to use Ampersand and/or Colon with Proc, Map, and Inject , and comment any useful Array method usages and tricks!  I may add more examples for Array here so be sure to check back!

As always I hope you’ve enjoyed this!  Please comment, share, subscribe to my RSS Feed, and follow me on twitter @6ftdan!

God Bless!
-Daniel P. Clark

Image by Tom Blackwell via the Creative Commons Attribution-NonCommercial 2.0 Generic License

#array#collection#example#examples#ruby

Comments

  1. digitalhub
    January 18, 2016 - 3:11 pm

    Fantastic resource! Bookmarked

  2. Ketan Shukla
    March 31, 2016 - 11:28 am

    This is such a fantastic article! Worthy of being bookmarked for reference! Thank you for this Dan!

  3. Cameron Seright
    September 26, 2016 - 12:08 pm

    Amazing resource, I learned so much! Thank you, Daniel. Here I was thinking I knew Arrays well =]

Leave a Reply

Your email address will not be published / Required fields are marked *