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

Time:09-15

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.

CodePudding user response:

If the logins are even indicies and logouts are odd indicies, it looks like you could do:

const events = [
  { action: 'login', timestamp: 10 },
  { action: 'logout', timestamp: 20 },
  { action: 'login', timestamp: 55 },
  { action: 'logout', timestamp: 65 },
]
function getUserSessionLength(events) {
  let userSession = 0
  for (let i = 0; i < events.length; i  = 2) {
    userSession  = events[i   1].timestamp - events[i].timestamp;
  }
  return userSession
}
console.log(getUserSessionLength(events));

If the final object might not exist (only a login but not logout has been recorded yet):

const events = [
  { action: 'login', timestamp: 10 },
  { action: 'logout', timestamp: 20 },
  { action: 'login', timestamp: 55 },
]
function getUserSessionLength(events) {
  let userSession = 0
  for (let i = 0; i < events.length - 1; i  = 2) {
    userSession  = events[i   1].timestamp - events[i].timestamp;
  }
  return userSession
}
console.log(getUserSessionLength(events));

CodePudding user response:

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)

  • Related