0

Its may be question from noob but, but I can't to make it...

I have array

arr = ["I", "wish", "I", "hadn't", "come"]

I need to do

[["I", "wish I hadn't come"], 
 ["I wish", "I hadn't come"],
 ["I wish I", "hadn't come"],
 ["I wish I hadn't", "come"]]

I understand how need to division that array:

Array.new(n) { Array[arr.shift(n).join(" "), arr.join(" ")] }

but n, I think, must change from 1 upto (arr.size - 1) to fill two-dimensional array with needed arrays. How to make it I don't understand.

1
  • @Stefan Thanks. I understood, I wrongly made new arrays. Commented May 23, 2016 at 10:58

4 Answers 4

2

This should work for you :

arr = ["I", "wish", "I", "hadn't", "come"]

new_arr = (0..arr.size-2).map {|i| [arr[0..i].join(" "), arr[i+1..-1].join(" ")] }

p new_arr

Which outputs :

[
  ["I", "wish I hadn't come"], 
  ["I wish", "I hadn't come"], 
  ["I wish I", "hadn't come"], 
  ["I wish I hadn't", "come"]
]
Sign up to request clarification or add additional context in comments.

5 Comments

Use map instead of each / push
Yup. You can also use #map to DRY-up the #joins: arr.size.pred.times.map { |i| [arr[0..i], arr[(i+1)..-1]].map { |a| a.join(' ') } }
@Pholochtairze Thanks. At last I understood mechanism. I broke my mind all week...
@Stefan : I tried a map version, is it how you thought of building it ? (I'm curious now)
Almost, you don't need el, so I'd write (1..arr.size).map { |i| ... }
1

Array#shift is destructive, it alters your array:

arr = ["I", "wish", "I", "hadn't", "come"]

[arr.shift(2).join(" "), arr.join(" ")]
#=> ["I wish", "I hadn't come"]

arr
#=> ["I", "hadn't", "come"]

You can use Array#[] instead:

arr = ["I", "wish", "I", "hadn't", "come"]

arr[0..2]
#=> ["I", "wish", "I"]

arr[3..-1]
#=> ["hadn't", "come"]

-1 refers to the last element.

Comments

0

You may want to consider using slice, which can return a select part of the array, rather than shift, which can achieve the same thing for the first n elements but modifies the original array in doing so. Combining this with your idea of looping from 1 to size-1 will help you reach your goal. The for i in 1..n do syntax is one way of doing this.

3 Comments

for loops are rarely used nowadays.
Good point. I thought the 1..n-1 syntax would help as the OP seems to understand the start and end indices he wants to use, but this would be a good opportunity to look into what else Ruby has to offer, e.g. times, or for this case map, as you suggested.
I had idea with loops and maybe I finded right decision, but I forgot required new array in the end
0

Here is one way to do this:

require "pp"

arr = ["I", "wish", "I", "hadn't", "come"]

r = (1...arr.size).collect  {|i| [arr.take(i).join(" "), arr.drop(i).join(" ")]}

pp r
#=> [["I", "wish I hadn't come"],
#   ["I wish", "I hadn't come"],
#   ["I wish I", "hadn't come"],
#   ["I wish I hadn't", "come"]]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.