# Help with complex array transformation

**URL:** <https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744>\
**Category:** Ruby\
**Created:** [December 3, 2009, 12:03am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744 "2009-12-03T00:03:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![m4lloc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/87869e/32.png) [@m4lloc](https://www.ruby-forum.com/u/m4lloc)\
**Post date:** [December 3, 2009, 12:03am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744/1 "2009-12-03T00:03:00Z")

</div>

Hi

I have a following method

view(all\_people, begin\_date, end\_date)

That’s give me an array like this:

# for a first day (day 1)

view("\*", ‘2009-12-01 00:00:00’, ‘2009-12-01 24:59:59’)

[[name\_person1, room1], [name\_person2, room2], [name\_person3, room2]]

# for a second day (day 2)

view("\*", ‘2009-12-02 00:00:00’, ‘2009-12-02 24:59:59’)

[[name\_person1, room1], [name\_person3, room1], [name\_person2, room2]]

And I need to organize theses arrays in a following structure:

[{room1 =\> [{day1 =\> [name\_person1]},  
{day2 =\> [name\_person1, name\_person3]}]  
},  
{room2 =\> [{day1 =\> [name\_person2, name\_person3]},  
{day2 =\> [name\_person2]}]  
}]

And finally put this array in a cvs strings

room1; day1; name\_person1  
room1; day2; name\_person1  
room1; day2; name\_person3

room2; day1; name\_person2  
room2; day1; name\_person3  
room2; day2; name\_person2

I tried some scripts for hours but I didn’t do this job!  
Too complicated for my.

Someone can help me if this?

Thanks so much!

---

<div class="post-metadata">

**Author:** ![m4lloc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/87869e/32.png) [@m4lloc](https://www.ruby-forum.com/u/m4lloc)\
**Post date:** [December 3, 2009, 4:01am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744/2 "2009-12-03T04:01:21Z")

</div>

Hi, Bruno,

```
 I'm not too sure if I fully understood you, but this shouldn't be 

```

too  
difficult in constructing the data structure, but quite of bit  
mind-blogging  
for sure…

Just make an array of hashes of arrays…a room array, such as

arrRoom = [ “0”,  
{“person”=\>[day1, day2,…], # this is for room1,  
arrRoom[1]  
{ #ditto for room2, arrRoom[2] } ]

Then based on the return value of your “view” method, you can do this:

# 1

view\_method(day1).each do |person, room|

```
 arrRoom[room]["person"]<<day1

```

end

#2  
view\_method(day2).each do |person, room|

```
 arrRoom[room]["person"]<<day2

```

end

(The above looks like it needs some code refactoring)

and finally, just run an each\_loop on the arrRoom, and deference  
all the hashes to get your result:

arrRoom.each do |room|  
next if arrRoom[0]  
arrRoom[room][person].each do |day|  
# puts arrRoom[room] + arrRoom[room][person][day] +   
# arrRoom[room][person]

# The above “puts” is not absolutely correctly, you need to re-structure

other “persons” into account…

end  
end  
**END**

Hopefully this pseudo code helps you thinking along the line…

---

<div class="post-metadata">

**Author:** ![m4lloc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/87869e/32.png) [@m4lloc](https://www.ruby-forum.com/u/m4lloc)\
**Post date:** [December 3, 2009, 5:32am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744/3 "2009-12-03T05:32:39Z")

</div>

Hi,

Am Donnerstag, 03. Dez 2009, 08:03:03 +0900 schrieb Bruno M.:

> And finally put this array in a cvs strings
> 
> room1; day1; name\_person1  
> room1; day2; name\_person1  
> room1; day2; name\_person3
> 
> room2; day1; name\_person2  
> room2; day1; name\_person3  
> room2; day2; name\_person2

Let `v' be the result of the`view’ call.

by\_room = Hash.new { |h,k| h[k] = Hash.new { |i,j| i[j] = [] } }  
days.each { |day|  
v = view something, day  
v.each { |(name,room)|  
by\_room[room][day].push name  
}  
}  
by\_room.each { |room,per\_day|  
per\_day.each { |day,name|  
puts [room,day,name].join(";")  
}  
}

Untestet and surely full of bugs at this complication level.  
Do yourself a favour and divide it into at least two method/block  
calls. Then consider about sorting…

Bertram

---

<div class="post-metadata">

**Author:** ![m4lloc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/87869e/32.png) [@m4lloc](https://www.ruby-forum.com/u/m4lloc)\
**Post date:** [December 3, 2009, 11:22am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744/4 "2009-12-03T11:22:38Z")

</div>

I should donate a each one paypal credits…rsss

Thanks so much Nik Z. ,Bertram and Robert !!!

You save my time and my head 😃

I should give for each one a credit donation by te paypal or for this  
forum : -)

I’ll apply theses snippets and modify them for my necessity.

This forum help me so much in a my painful journey with ruby rails.

Thanks again!

Best Regards!

---

<div class="post-metadata">

**Author:** ![m4lloc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/87869e/32.png) [@m4lloc](https://www.ruby-forum.com/u/m4lloc)\
**Post date:** [December 3, 2009, 9:16am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744/5 "2009-12-03T09:16:46Z")

</div>

2009/12/3 Bruno M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I have a following method
> 
> view(all\_people, begin\_date, end\_date)
> 
> That’s give me an array like this:
> 
> # for a first day (day 1)
> 
> view(“\*”, ‘2009-12-01 00:00:00’, ‘2009-12-01 24:59:59’)

I would rather change timestamp strings into objects of class Time or  
DateTime because that is what they are You can do proper comparison  
etc. I am aware that you can also do that with your string format but  
if it is a timestamp it’s usually better to treat it as such.

> [{room1 =\> [{day1 =\> [name\_person1]},  
> {day2 =\> [name\_person1, name\_person3]}]  
> },  
> {room2 =\> [{day1 =\> [name\_person2, name\_person3]},  
> {day2 =\> [name\_person2]}]  
> }]

Why so many nesting levels? Why not

{room1 =\> [{day1 =\> [name\_person1]},  
{day2 =\> [name\_person1, name\_person3]}]  
},  
{room2 =\> [{day1 =\> [name\_person2, name\_person3]},  
{day2 =\> [name\_person2]}]  
}

Or even

{room1 =\> {day1 =\> [name\_person1]},  
{day2 =\> [name\_person1, name\_person3]}  
},  
{room2 =\> {day1 =\> [name\_person2, name\_person3]},  
{day2 =\> [name\_person2]}  
}

Methinks you are making the structure much more complex than  
necessary, especially in light of the desired output:

> I tried some scripts for hours but I didn’t do this job!  
> Too complicated for my.

See Bertram’s solution. I would have done it a bit different, mainly  
including sorting.

room\_day\_assignments = Hash.new {|h,k| h[k] = Hash.new {|a,b| a[b] = []}  
}

days.each do |day|  
v = view…  
v.each do |person, room|  
room\_day\_assignments[room][day] \<\< person  
end  
end

# output

room\_day\_assignments.keys.sort.each do |room|  
room\_day = room\_day\_assignments[room]  
room\_day.keys.sort.each do |day|  
room\_day[day].each do |person|  
printf “%s;%s;%s\n”, room, day, person  
end  
end  
end

Untested.

Cheers

robert

---

<div class="post-metadata">

**Author:** ![m4lloc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/87869e/32.png) [@m4lloc](https://www.ruby-forum.com/u/m4lloc)\
**Post date:** [December 3, 2009, 11:27am UTC](https://www.ruby-forum.com/t/help-with-complex-array-transformation/179744/6 "2009-12-03T11:27:06Z")

</div>

And Robert

I agree with you. My data structure is much complex for a information  
that I need work. I like of your way to express a better output  
solution.

Thanks so much again!

Bruno M. wrote:

> I should donate a each one paypal credits…rsss
> 
> Thanks so much Nik Z. ,Bertram and Robert !!!
> 
> You save my time and my head 😃
> 
> I should give for each one a credit donation by te paypal or for this  
> forum : -)
> 
> I’ll apply theses snippets and modify them for my necessity.
> 
> This forum help me so much in a my painful journey with ruby rails.
> 
> Thanks again!
> 
> Best Regards!
