Arel
Arel

Reputation: 3938

How do I repeat certain items in an array based on matched values in another array?

I've been trying for a couple weeks to figure this out, but I'm totally stumped.

I have an array that represents item_id's: [2, 4, 5, 6, 2, 3].

I have another array that represents how many times each item shows up: [1, 1, 3, 3, 2, 5] .

I want to check that all items have been completed so I want to create an array that has the total number of item_id's in it. I will compare that array against a completed items array that will be created as the user completes each item, so, from the example above, the array I'm trying to create is:

[2, 4, 5, 5, 5, 6, 6, 6, 2, 2, 3, 3, 3, 3, 3]

EDIT:

I'm building a workout app, so a user has a workout which has many exercises. Each exercise has one or more sets associated with it. The user completes an exercise when he has completed every set for that exercise, and completes a workout when he completes all exercises for that workout. In this question I'm trying to determine when a user has finished a workout.

EDIT 2:

I wish I could award multiple right answers! Thanks everyone!

Upvotes: 0

Views: 729

Answers (4)

Danil Speransky
Danil Speransky

Reputation: 30453

Ok, @sameera207 suggested one way, then I will suggest another way (functional style):

arr1 = [2, 4, 5, 6, 2, 3]
arr2 = [1, 1, 3, 3, 2, 5]

arr1.zip(arr2).flat_map { |n1, n2| [n1] * n2 }

Upvotes: 5

davogones
davogones

Reputation: 7399

item_ids = [2, 4, 5, 6, 2, 3]
counts = [1, 1, 3, 3, 2, 5]
item_ids.zip(counts).map{|item_id,count| [item_id]*count}.flatten
 => [2, 4, 5, 5, 5, 6, 6, 6, 2, 2, 3, 3, 3, 3, 3]

What's going on here? Let's look at it step by step.

zip takes two arrays and "zips" them together element-by-element. I did this to create an array of item_id, count pairs.

item_ids.zip(counts)
 => [[2, 1], [4, 1], [5, 3], [6, 3], [2, 2], [3, 5]]

map takes each element of an array and executes a block. In this case, I'm using the * operator to expand each item_id into an array of count elements.

[1]*3 => [1, 1, 1]
[[2, 1], [4, 1], [5, 3], [6, 3], [2, 2], [3, 5]].map{|item_id,count| [item_id]*count}
 => [[2], [4], [5, 5, 5], [6, 6, 6], [2, 2], [3, 3, 3, 3, 3]]

Finally, flatten takes an array of arrays and "flattens" it down into a 1-dimensional array.

[[2], [4], [5, 5, 5], [6, 6, 6], [2, 2], [3, 3, 3, 3, 3]].flatten
 => [2, 4, 5, 5, 5, 6, 6, 6, 2, 2, 3, 3, 3, 3, 3]

Upvotes: 4

sameera207
sameera207

Reputation: 16629

This is a one way of doing it:

a = [2,4,5,6,2,3]
b = [1,1,3,3,2,5]
c = []

a.each.with_index do |index, i|
  b[index].to_i.times {c << i }
end
p c

Upvotes: 1

enthrops
enthrops

Reputation: 729

ids = [2, 4, 5, 6, 2, 3]
repeats = [1, 1, 3, 3, 2, 5]

result = []
ids.count.times do |j|
  repeats[j].times { result << ids[j] }
end

Upvotes: 1

Related Questions