Reputation: 11
array = [
["sean", "started", "shift", "at", "10:30:00"],
["anna", "started", "shift", "at", "11:00:00"],
["sean", "started", "shift", "at", "10:41:45"],
["anna", "finished", "shift", "at", "11:30:00"],
["sean", "finished", "shift", "at", "10:48:45"],
["sean", "started", "shift", "at", "11:31:00"],
["sean", "finished", "shift", "at", "11:40:00"]
]
Few things to consider
if you look at sean's entries - there are 2 entries for 'start times' one at 10:30:00 and also at 10:41:45 . The system can record multiple 'start times' but only one 'Finished' time. The logic is to pair first 'started' & first 'finished' and combine them.
How to skip the duplicated 'start time' entries (such as Sean's) and get a desired output as below...
array = [
["sean", "started", "shift", "at", "10:30:00", "finished", "shift", "at", "10:48:45"],
["anna", "started", "shift", "at", "11:00:00", "finished", "shift", "at", "11:30:00"],
["sean", "started", "shift", "at", "11:31:00", "finished", "shift", "at", "11:40:00"]
]
Theres no easy way is it?
Upvotes: 0
Views: 75
Reputation: 37419
array.group_by(&:first).map do |person, events|
events.chunk { |_, event_type| event_type }.each_slice(2).map do |(_, (start, _)), (_, (finish, _))|
%W(#{p} started shift at #{start[4]} finished shift at #{finish[4]})
end
end
# => [
# => ["sean", "started", "shift", "at", "10:30:00", "finished", "shift", "at", "10:48:45"],
# => ["sean", "started", "shift", "at", "11:31:00", "finished", "shift", "at", "11:40:00"],
# => ["anna", "started", "shift", "at", "11:00:00", "finished", "shift", "at", "11:30:00"]
# => ]
Upvotes: 1
Reputation: 198496
started = {}
result = []
array.each do |name, *event|
if event[0] == "started" && !started[name]
result << (started[name] = [name] + event)
elsif event[0] == "finished" && started[name]
started[name].concat(event)
started[name] = nil
end
end
result
EDIT Completely agree with fotanus, BTW.
EDIT2 Forgot to change a variable name. Also: logic. You take each row in turn. started
will contain any records that have started but not yet finished. So, take a row; if it's "started", and only if we don't know that that person already started, remember the start. If it's "finished", and only if we already know the person has started, finish up the record by appending the finish info.
Upvotes: 0