Skip to content

Instantly share code, notes, and snippets.

@martfl
Created April 24, 2019 00:31
Show Gist options
  • Save martfl/52d48b5e2b576d99eee06eab1c8428d9 to your computer and use it in GitHub Desktop.
Save martfl/52d48b5e2b576d99eee06eab1c8428d9 to your computer and use it in GitHub Desktop.
const humanSize = bytes => {
if (!bytes || isNaN(bytes) || bytes < 0 ) return null
const metric = {'decimal': 1000,'binary': 1024}
const units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
/*
reduce takes a callback and an initial value.
callback acts upon every element of the array, and should return at
every loop an accumulated value;which is the input for the next loop.
*/
return units.reduce((acc, unit) => {
if (typeof acc === 'string') {
// being here means that we have a correct value with its corresponding unit.
// we have to traverse the whole array so we just return the same result. little caveat 🤷🏻‍♂️
return acc
} else if (acc > 1000) {
// a number bigger than 1000 means that we should use the next bigger unit.
return acc = (acc / metric.binary)
} else {
// time to attach the corresponding unit, and round decimals.
// if number is already an Integer just return it, we don't want additional zeroes 😖
return Number.isInteger(acc) ? acc + unit : acc.toFixed(1) + unit
}
} , bytes)
}
humanSize(10000) // 9.8kB
humanSize(999) // 999B
humanSize(1) // 1B
for (let i= 1; i < 10; i++) {
humanSize(Math.pow(1024, i)) // let's just test each unit
}
humanSize(-2) // null
humanSize("") // null
humanSize(undefined) // null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment