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

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.