Human readable duration format

SungJunEun·2021년 11월 16일
0

Codewars 문제풀이

목록 보기
16/26
post-thumbnail

Description:

Your task in order to complete this Kata is to write a function which formats a duration, given as a number of seconds, in a human-friendly way.

The function must accept a non-negative integer. If it is zero, it just returns "now". Otherwise, the duration is expressed as a combination of yearsdayshoursminutes and seconds.

It is much easier to understand with an example:

formatDuration(62) // returns "1 minute and 2 seconds"
formatDuration(3662) // returns "1 hour, 1 minute and 2 seconds"

For the purpose of this Kata, a year is 365 days and a day is 24 hours.

Note that spaces are important.

Detailed rules

The resulting expression is made of components like 4 seconds1 year, etc. In general, a positive integer and one of the valid units of time, separated by a space. The unit of time is used in plural if the integer is greater than 1.

The components are separated by a comma and a space (", "). Except the last component, which is separated by " and ", just like it would be written in English.

A more significant units of time will occur before than a least significant one. Therefore, 1 second and 1 year is not correct, but 1 year and 1 second is.

Different components have different unit of times. So there is not repeated units like in 5 seconds and 1 second.

A component will not appear at all if its value happens to be zero. Hence, 1 minute and 0 seconds is not valid, but it should be just 1 minute.

A unit of time must be used "as much as possible". It means that the function should not return 61 seconds, but 1 minute and 1 second instead. Formally, the duration specified by of a component must not be greater than any valid more significant unit of time.

My solution:

function formatDuration (seconds) {
  const years = (seconds- seconds % 31536000) / 31536000;
  const days = parseInt((seconds % 31536000) / 86400);
  const hours = parseInt((seconds % 86400) / 3600);
  const minutes = parseInt((seconds % 3600) / 60);
  const second = parseInt(seconds % 60);
  let object = {a: years, b: days, c: hours, d: minutes, e: second};
  for(item of Object.keys(object)) {
    if(item == "a") {
      object[item] += " year";
    } else if(item == "b") {
      object[item] += " day";
    } else if(item == "c") {
      object[item] += " hour";
    } else if(item == "d") {
      object[item] += " minute";
    } else if(item == "e") {
      object[item] += " second";
    }

    if(object[item].match(/(\d+)/)[0] >1) {
      object[item] += "s";
    }

    if(object[item].match(/(\d+)/)[0] == 0) {
      delete object[item];
    }
  }
  let array = Object.values(object);
  for(i=0; i<array.length; i++) {
    if(array.length>1 && i==array.length-2) {
      array[i]+=" and ";
    } else if(i == array.length-1) {
      continue;
    } else {
      array[i]+=", ";
    }
  }
  const newstring = array.join('');
  if(newstring == ""){
    return 'now';
  }

  return newstring;
}

Best solutions:

function formatDuration (seconds) {
  var time = { year: 31536000, day: 86400, hour: 3600, minute: 60, second: 1 },
      res = [];

  if (seconds === 0) return 'now';

  for (var key in time) {
    if (seconds >= time[key]) {
      var val = Math.floor(seconds/time[key]);
      res.push(val += val > 1 ? ' ' + key + 's' : ' ' + key);
      seconds = seconds % time[key];
    }
  }

  return res.length > 1 ? res.join(', ').replace(/,([^,]*)$/,' and'+'$1') : res[0]
}
  • 오브젝트에 for ... in 문

    을 하면, key가 순서대로 반환된다.

  • 정규 표현식 /,([^,]*)$/ 이해하기

    • [^,]
      • [a,b,c] : a || b || c||
      • [^a-z]: not a~z
    • * 이전 패턴를 0개 이상 만족하는 문자열을 반환한다.
    • $ 문장의 끝

    → ,로 시작하는 ,을 포함하지 않는 문장이 끝나는 부분에 있는 문자열

  • 정규표현식 () 와 $1

    정규표현식에서 ()는 ()안에 있는 문자열을 포획하여서 기억한다. 그리고 $1을 통해서 접근이 가능하다. 만약에 ()가 3개 있다면, $1, $2, $3으로 순서대로 해당 문자열을 반환할 수 있다.

profile
블록체인 개발자(진)

0개의 댓글