jnorris
jnorris

Reputation: 6500

How to get "string-like" join functionality for arrays in Ruby

Consider the following input:

input = [:a, :b, :c]
# output = input.join_array(:x)

What is a readable and concise way to get the following output (in Ruby):

[:a, :x, :b, :x, :c]

Upvotes: 0

Views: 147

Answers (5)

Arup Rakshit
Arup Rakshit

Reputation: 118271

How is this ?

input = [:a, :b, :c]
p input.each_with_object(:x).to_a.flatten[0..-2]
# >> [:a, :x, :b, :x, :c]

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

A naive approach:

input = [:a, :b, :c]

input.flat_map{|elem| [elem, :x]}[0...-1] # => [:a, :x, :b, :x, :c]

Without cutting last element:

res = input.reduce([]) do |memo, elem|
  memo << :x unless memo.empty?
  memo << elem
end

res # => [:a, :x, :b, :x, :c]

Upvotes: 3

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84363

Flatten a Product

You can use Array#product to distribute :x throughout your array, and then flatten the result. For example:

input = [:a, :b, :c]
input.product([:x]).flatten
#=> [:a, :x, :b, :x, :c, :x]

Trimming an Array

Assuming your desired result wasn't just a typo that accidentally excluded the last element, you can use Array#pop, Array#slice, or other similar methods to trim the last element from the array. Some examples include:

input.product([:x]).flatten[0...-1]
#=> [:a, :x, :b, :x, :c]

output = input.product([:x]).flatten
output.pop
output
#=> [:a, :x, :b, :x, :c]

Upvotes: 2

hirolau
hirolau

Reputation: 13901

What about:

input = [:a, :b, :c]
p input.zip([:x].cycle).flatten[0..-2] #=> [:a, :x, :b, :x, :c]

Upvotes: 1

BaronVonBraun
BaronVonBraun

Reputation: 4293

For fun, we could use join. Not necessarily readable or concise though!

[:a, :b, :c].join('x').chars.map(&:to_sym) # => [:a, :x, :b, :x, :c]

# Or, broken down:
input = [:a, :b, :c]
output = input.join('x')      # => "axbxc"
output = output.chars         # => ["a", "x", "b", "x", "c"]
output = output.map(&:to_sym) # => [:a, :x, :b, :x, :c] 

Upvotes: 0

Related Questions