75 lines
1.8 KiB
GDScript3
Raw Permalink Normal View History

2025-01-11 00:25:52 +01:00
class HashSet:
var _comparer : Callable
var _set : Array
func _init(comparer : Callable):
self._comparer = comparer
self._set = []
static func array_index_of_comparer(
array : Array, item, comparer : Callable
):
for i in range(array.size()):
var a = array[i]
if comparer.call(a, item):
return i
return -1
func push(value):
var ret_value = HashSet.array_index_of_comparer(self._set, value, self._comparer) == -1
if ret_value:
self._set.append(value)
return ret_value
static func distinct_(
key_mapper : Callable = GDRx.basic.identity,
comparer : Callable = GDRx.basic.default_comparer
) -> Callable:
var comparer_ = comparer
var distinct = func(source : Observable) -> Observable:
# """Returns an observable sequence that contains only distinct
# elements according to the key_mapper and the comparer. Usage of
# this operator should be considered carefully due to the
# maintenance of an internal lookup structure which can grow
# large.
#
# Examples:
# >>> var obs = distinct.call(source)
#
# Args:
# source: Source observable to return distinct items from.
#
# Returns:
# An observable sequence only containing the distinct
# elements, based on a computed key value, from the source
# sequence.
# """
var subscribe = func(
observer : ObserverBase,
scheduler : SchedulerBase = null
) -> DisposableBase:
var hashset = HashSet.new(comparer_)
var on_next = func(x):
var key = RefValue.Set(x)
if GDRx.try(func():
key.v = key_mapper.call(key.v)
) \
.catch("Error", func(err):
observer.on_error(err)
) \
.end_try_catch(): return
if hashset.push(key.v):
observer.on_next(x)
return source.subscribe(
on_next, observer.on_error, observer.on_completed,
scheduler
)
return Observable.new(subscribe)
return distinct