diff --git a/source/funkin/utils/tools/ArrayTools.hx b/source/funkin/utils/tools/ArrayTools.hx index fa334755..7e015cb6 100644 --- a/source/funkin/utils/tools/ArrayTools.hx +++ b/source/funkin/utils/tools/ArrayTools.hx @@ -3,8 +3,8 @@ package funkin.utils.tools; class ArrayTools { /** - * Clears this array in place - * @param array + * Clears this array in place. + * @param array * @return Array */ public static function clear(array:Array):Array @@ -13,4 +13,114 @@ class ArrayTools array.pop(); return array; } + + /** + * Shuffles this array in place using Fisher-Yates. + * @param array + * @return Array + */ + public static function shuffle(array:Array):Array + { + var i = array.length; + while (i > 1) + { + var j = Std.int(Math.random() * i--); + swap(array, i, j); + } + return array; + } + + /** + * Returns the last element, or null if empty. + * @param array + * @return Null + */ + public static function last(array:Array):Null + { + return array.length > 0 ? array[array.length - 1] : null; + } + + /** + * Removes duplicate values from this array in place. + * @param array + * @return Array + */ + public static function unique(array:Array):Array + { + var seen:Array = []; + var i = 0; + while (i < array.length) + { + if (seen.indexOf(array[i]) != -1) + array.splice(i, 1); + else + seen.push(array[i++]); + } + return array; + } + + /** + * Returns a new array with all elements from both arrays, without duplicates. + * @param a + * @param b + * @return Array + */ + public static function union(a:Array, b:Array):Array + { + var result = a.copy(); + for (item in b) + if (result.indexOf(item) == -1) + result.push(item); + return result; + } + + /** + * Swaps two elements in place by index. + * @param array + * @param i + * @param j + */ + public static function swap(array:Array, i:Int, j:Int):Void + { + var tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; + } + + /** + * Groups elements by a key returned from fn, returning a map of key to matching elements. + * @param array + * @param fn + * @return Map> + */ + public static function groupBy(array:Array, fn:T->K):Map> + { + var map = new Map>(); + for (item in array) + { + var key = fn(item); + if (!map.exists(key)) + map.set(key, []); + map.get(key).push(item); + } + return map; + } + + /** + * Splits the array into sub-arrays of the given size. + * @param array + * @param size + * @return Array> + */ + public static function chunk(array:Array, size:Int):Array> + { + var result:Array> = []; + var i = 0; + while (i < array.length) + { + result.push(array.slice(i, i + size)); + i += size; + } + return result; + } }