Dave
Dave

Reputation: 19120

In Ruby, how do I replace an element in an array with potentially multiple elements?

Using Ruby 2.4. I have an array of strings. How do I replace one element in an array with potentially multiple elements? I have

phrases[index] = tokens 

However tokens is an array and right now this results in a phrases array with strings and an array ...

["abc", ["a", "b"], "123"]

If tokens is ["a", "b"] and index is 1, I would like teh result to be

["abc", "a", "b", "123"]

How do I do that?

Upvotes: 4

Views: 2357

Answers (3)

baweaver
baweaver

Reputation: 306

Flat map would be a better way to go about it, it maps (transforms) then flattens the list to a single array. Say we wanted to add two elements for even numbers:

(1..10).flat_map { |i| i.even? ? [i, i**2] : i }

It would return:

[1, 2, 4, 3, 4, 16, 5, 6, 36, 7, 8, 64, 9, 10, 100]

As compared to map which would return:

[1, [2, 4], 3, [4, 16], 5, [6, 36], 7, [8, 64], 9, [10, 100]]

Upvotes: 0

Cary Swoveland
Cary Swoveland

Reputation: 110675

You can use Enumerable#flat_map:

arr = ["abc", ["a", "b"], "123"]

arr.flat_map(&:itself)
  #=> ["abc", "a", "b", "123"] 

arr is unchanged. To modify arr in place,

arr.replace(arr.flat_map(&:itself))
  #=> ["abc", "a", "b", "123"] 
arr
  #=> ["abc", "a", "b", "123"] 

Upvotes: 1

falsetru
falsetru

Reputation: 369054

You can specify start and length with Array#[]=; replaces a sub-array from the start index for length elements

or specify range; replaces a sub-array specified by the range of indices.

phrases = ["abc", "token_placeholder", "123"]
tokens = ["a", "b"]
index = 1
phrases[index, 1] = tokens
#       ^^^^^^^^^ ------------------ start and length

# OR phrases[index..index] = tokens
#            ^^^^^^^^^^^^ -------------- range

phrases # => ["abc", "a", "b", "123"]

Upvotes: 5

Related Questions