# Help with complex array transformation

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!

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…

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

Bertram

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!

2009/12/3 Bruno M. [email protected]:

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

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!