Skip to content
Advertisement

Is there a cleaner way to calculate user session length from such an array?

I have an array of events where every event has an action (login/logout) and a timestamp.

const events = [
  { action: 'login', timestamp: 10 },
  { action: 'logout', timestamp: 20 },
  { action: 'login', timestamp: 55 },
  { action: 'logout', timestamp: 65 },
]

I am trying to write a function calculating the total user session length which is defined by the difference between a login and logout. And a login always comes before a logout.

function getUserSessionLength(events) {
  let userSession = 0
  let lastTimeLogIn = 0
  for (const { action, timestamp } of events) {
    if (action === 'login') lastTimeLogIn = timestamp
    else userSession += timestamp - lastTimeLogIn
  }

  return userSession
}

This works but I wonder if there is a simpler or cleaner way to calculate it? Right now I need to use an extra variable to keep track of the last login timestamp while traversing the array.

Advertisement

Answer

If login events are always followed by logout events, you can simply subtract the sum of the login timestamps from the sum of the logout timestamps:

const events = [
  { action: 'logout', timestamp: 3 },
  { action: 'login', timestamp: 10 },
  { action: 'logout', timestamp: 20 },
  { action: 'login', timestamp: 55 },
  { action: 'logout', timestamp: 65 },
  { action: 'login', timestamp: 85 },
]

userSessionLength = events
  // make sure we start with login
  .slice(events.findIndex(e => e.action == 'login'),
         events.length - events.slice(0).reverse().findIndex(e => e.action == 'logout'))
  .reduce((acc, { action, timestamp }) => acc + (action == 'logout' ? timestamp : -timestamp)
, 0)

console.log(userSessionLength)
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement