import {MapUtils} from './MapUtils'; import {SetUtils} from './SetUtils'; import {CoreType} from './Type'; export class ArrayUtils { static min(array: Array): T { let min = array[0]; for (let element of array) { if (element < min) { min = element; } } return min; } static max(array: Array): T { let min = array[0]; for (let element of array) { if (element > min) { min = element; } } return min; } static sum(array: number[]): number { let sum = 0; for (let element of array) { sum += element; } return sum; } static compact(array: Array): Array { const newArray: Array = []; for (let elem of array) { if (elem != null) { newArray.push(elem); } } return newArray; } static uniq(array: Array): Array { const tmpSet: Set = new Set(); for (let elem of array) { tmpSet.add(elem); } const newArray: Array = new Array(tmpSet.size); let i = 0; tmpSet.forEach((elem) => { newArray[i] = elem; i++; }); return newArray; } static chunk(array: Array, chunkSize: number): Array> { const newArray: Array> = []; let newSubArray: Array = []; newArray.push(newSubArray); for (let i = 0; i < array.length; i++) { if (newSubArray.length == chunkSize) { newSubArray = []; newArray.push(newSubArray); } newSubArray.push(array[i]); } return newArray; } static union(array0: Array, array1: Array): Array { const newArray: Array = []; const unionSet = SetUtils.union(this.toSet(array0), this.toSet(array1)); unionSet.forEach((val) => newArray.push(val)); return newArray; } static intersection(array0: Array, array1: Array): Array { const newArray: Array = []; const intersectionSet = SetUtils.intersection(this.toSet(array0), this.toSet(array1)); intersectionSet.forEach((val) => newArray.push(val)); return newArray; } static difference(array0: Array, array1: Array): Array { const newArray: Array = []; const differenceSet = SetUtils.difference(this.toSet(array0), this.toSet(array1)); differenceSet.forEach((val) => newArray.push(val)); return newArray; } static toSet(array: Array): Set { const set: Set = new Set(); for (let elem of array) { set.add(elem); } return set; } static isEqual(array0: Array, array1: Array): boolean { if (array0.length != array1.length) { return false; } const count = array0.length; for (let i = 0; i < count; i++) { if (array0[i] != array1[i]) { return false; } } return true; } static sortBy(array: Array, callback: (e: T) => K): Array { if (array.length == 0) { return []; } const elementsByValue: Map = new Map(); const valuesSet: Set = new Set(); for (let elem of array) { const value: K = callback(elem); valuesSet.add(value); MapUtils.push_on_array_at_entry(elementsByValue, value, elem); } const values: K[] = new Array(valuesSet.size); let i = 0; valuesSet.forEach((value) => { values[i] = value; i++; }); // sort differently if the callback return value is a string or a number if (CoreType.isString(values[0])) { values.sort(); } else { values.sort((a, b) => (a as number) - (b as number)); } const sorted_elements: Array = new Array(array.length); i = 0; for (let value of values) { const elements_for_value = elementsByValue.get(value); if (elements_for_value) { for (let element of elements_for_value) { sorted_elements[i] = element; i++; } } } return sorted_elements; } static range(start: number, end?: number, step: number = 1): number[] { if (end == null) { end = start; start = 0; } const length = Math.floor((end - start) / step); const array: number[] = new Array(length); for (let i = 0; i < array.length; i++) { array[i] = start + i * step; } return array; } }