if not globals.hasIndex("UTIL_DEFINED") then list.flatten = function() t = null ret = null if self isa list then t = list ret = [] else if self isa map then t = map ret = {} end if for i in self if @i isa t then ret = ret + i.flatten if not @i isa t then ret.push(@i) end for return ret end function map.flatten = @list.flatten list.flatMap = function(func, inst = null) t = null ret = null if self isa list then t = list ret = [] else if self isa map then t = map ret = {} end if for i in self.indexes obj = funcRef.invoke(@func, self[@i], inst) if @obj isa t then ret = ret + obj.flatten if not @obj isa t then ret.push(@obj) end for return ret end function map.flatMap = @list.flatMap list.filter = function(func, inst = null) ret = null if self isa list then ret = [] if self isa map then ret = {} for i in self.indexes if not funcRef.invoke(@func, @self[@i], @inst) then continue if ret isa list then ret.push(self[@i]) if ret isa map then ret[@i] = @self[@i] end for return ret end function map.filter = @list.filter list.filterKv = function(func, inst = null) ret = null if self isa list then ret = [] if self isa map then ret = {} for i in self.indexes arg = {"key": @i, "value": @self[@i]} if not funcRef.invoke(@func, arg, @inst) then continue if ret isa list then ret.push(self[@i]) if ret isa map then ret[@i] = @self[@i] end for return ret end function map.filterKv = @list.filterKv list.forEach = function(func, inst = null) for i in self funcRef.invoke @func, @i, @inst end for return self end function map.forEach = @list.forEach list.forEachKv = function(func, inst = null) for i in self.indexes funcRef.invoke @func, {"key": @i, "value": @self[@i]}, @inst end for return self end function map.forEachKv = @list.forEachKv list.findOrElse = function(self, func, default = null, inst = null) for val in self.values if @func isa funcRef and funcRef.invoke(@func, @val, @inst) then return @val if not @func isa funcRef and @val == func then return @val end for return @default end function map.findOrElse = @list.findOrElse list.find = @list.findOrElse map.find = @list.find list.findIsa = function(type, default = null) for val in self.values if val isa @type then return val end for return default end function list.getOrElse = function(key, default) if not self.hasIndex(@key) then return @default return self[@key] end function map.getOrElse = @list.getOrElse list.ifEmptyThen = function(default) if self.len == 0 then return default return self end function map.ifEmptyThen = @list.ifEmptyThen list.map = function(func, inst = null) ret = null if self isa list then ret = [] if self isa map then ret = {} for i in self.indexes if self isa list then ret.push funcRef.invoke(@func, @self[i], inst) if self isa map then ret[@i] = funcRef.invoke(@func, @self[@i], inst) end for return ret end function map.map = @list.map list.mapUnless = function(func, abortType) ret = null if self isa list then ret = [] if self isa map then ret = {} for i in self.indexes e = func(@self[@i]) if e isa abortType then return @e if self isa list then ret.push @e if self isa map then ret[@i] = @e end for return ret end function map.mapUnless = @list.mapUnless list.tryGet = function(key) return self.getOrElse(@key, null) end function map.tryGet = @list.tryGet list.tryPush = function(value) if @value then self.push(@value) return self end function map.tryPush = @list.tryPush list.trySeek = function(keys, default = null) ptr = self for key in keys if not ptr.hasIndex(@key) then return default ptr = ptr[@key] end for return ptr end function map.trySeek = @list.trySeek list.unique = function() i = 0 k = self.len - 2 while i <= k obj = self[i] for j in range(self.len - 1, i + 1) if self[i] == self[j] then self.remove(j) end for i = i + 1 k = self.len - 2 end while return self end function map.addRange = function(a, b) for i in a.indexes self[a[i]] = b[i] end for return self end function map.addInverse = function() for kv in self self[@kv.value] = @kv.key end for return self end function funcRef.curry = function(inst, toCurry, reverse = false) ret = function(obj) if reverse then return toCurry(@obj, @outer.inst) return toCurry(@outer.inst, @obj) end function return @ret end function funcRef.invoke = function(func, arg, inst = null) if @inst then return func(@inst, @arg) return func(@arg) end function globals.UTIL_DEFINED = true end if