0

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]
3
  • possible duplicate of How to insert a new element in between all elements of a Ruby array? Commented Oct 30, 2013 at 15:06
  • 2
    the name of the abstraction is "intersperse", you'll find some existing questions by that name. Commented Oct 30, 2013 at 15:07
  • Thanks, the name "intersperse" is exactly what I was looking for! Commented Oct 30, 2013 at 15:09

5 Answers 5

3

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]
Sign up to request clarification or add additional context in comments.

4 Comments

Upvoted, I think .flat_map{|elem| [elem, :x]}[0...-1] would be a little bit more readable though.
You can't use [0..-1], it'll include trailing :x.
Notice the third dot ... which makes the range exclusive
@BeatRichartz: ah! So you see, for some people it's just more confusing :)
2

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]

Comments

1

What about:

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

Comments

0

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] 

1 Comment

It's not robust. Will break down on longer symbols :)
0

How is this ?

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.