/**
* @author: K. Lae Kettavong
*
* @date: 3/06/19
*
* @description: Leveraging ES6 to demonstrate OOP using classes that inherit and extend native Array class to encapsulate and
* separate data type-driven tasks and enforce strict typing within data collection.
*
* Used 'Aire' prefix naming convention to align with https://www.npmjs.com/settings/laekettavong/packages
*
* AireRay extends Array
* AireRayString extends AireRay
* AireRayNumber extends AireRay
* AireRayBoolean extends AireRay
*
*/
const log = console.log
class AireRay extends Array {
constructor(...args) { super(...args) }
size() { return this.length }
isEmpty() { return this.length === 0 }
isBoolean(ele) { return typeof(ele) === 'boolean' }
isNumber(ele) { return typeof(ele) === 'number' }
isString(ele) { return typeof(ele) === 'string' }
containsDataType(type) {
return this.find(ele => typeof(ele) === type.toLowerCase()) !== undefined
}
hasUniformDataType() {
let ndx = 0
while (ndx < this.length - 1) {
if(typeof(this[ndx]) !== typeof(this[++ndx])) return false
}
return true
}
removeEmpties() {
this.filter(word => { if(word) return word })
}
}
/* String Container */
class AireRayString extends AireRay {
constructor(...args){
super(...args)
this.validateType()
}
push(ele){
if(!this.isString(ele)) this.throwTypeError()
super.push(ele)
}
sort() {
this.sort((a,b) => {
if (a > b) return 1
if (a < b) return -1
return 0
})
}
reverseSort() {
this.sort((a,b) => {
if (a < b) return 1
if (a > b) return -1
return 0
})
}
isStringsOnly() {
return this.find(ele => !this.isString(ele)) === undefined
}
validateType(){
if(!this.isStringsOnly()) this.throwTypeError()
}
throwTypeError() {
throw new TypeError('AireRayString must contain only strings')
}
}
/* Number Container */
class AireRayNumber extends AireRay {
constructor(...args){
super(...args)
this.validateType()
}
push(ele){
if(!this.isNumber(ele)) this.throwTypeError()
super.push(ele)
}
isSortedAsc() {
let ndx = 0
while (ndx < this.length - 1) {
if(this[ndx] > this[++ndx]) return false
}
return true
}
isSortedDesc() {
let ndx = 0
const reverse = [...this].reverse()
while (ndx < this.length - 1) {
if(this[ndx] < this[++ndx]) return false
}
return true
}
sortAsc() { this.sort((a,b) => a - b) }
sortDesc() { this.sort((a,b) => b - a) }
isNumbersOnly() {
return this.find(ele => !this.isNumber(ele)) === undefined
}
validateType() {
if(!this.isNumbersOnly()) this.throwTypeError()
}
throwTypeError() {
throw new TypeError('AireRayNumber must contain only numbers')
}
}
/* Boolean Container */
class AireRayBoolean extends AireRay {
constructor(...args){
super(...args)
this.validateType()
}
push(ele){
if(!this.isBoolean(ele)) this.throwTypeError()
super.push(ele)
}
isAllTrue() {
return this.find(ele => ele === false ) === undefined
}
isAllFalse() {
return this.find(ele => ele === true ) === undefined
}
isBooleansOnly() {
return this.find(ele => !this.isBoolean(ele)) === undefined
}
validateType(){
if(!this.isBooleansOnly()) this.throwTypeError()
}
throwTypeError() {
throw new TypeError('AireRayBoolean must contain only booleans')
}
}
const numArray = new AireRayNumber(1,2,3)
log('isEmpty()', numArray, numArray.isEmpty())
log('size()', numArray, numArray.size())
numArray.push(4)
numArray.push(15)
numArray.push(6)
//numArray.push(undefined)
log('isSortedAsc()', numArray.isSortedAsc())
numArray.sortDesc()
log('isSortedDesc()', numArray.isSortedDesc())
log('isSortedAsc()', numArray.isSortedAsc())
log(numArray)
numArray.sortAsc()
log(numArray)