erg/crates/erg_compiler/lib/std/_erg_array.py
2023-08-28 15:33:58 +09:00

74 lines
2.4 KiB
Python

from _erg_control import then__
from _erg_range import Range
from _erg_nat import NatMut
from _erg_int import IntMut
from _erg_contains_operator import contains_operator
class Array(list):
def try_new(arr): # -> Result[Array]
if isinstance(arr, list):
return Array(a)
else:
return Error("not a list")
def dedup(self, same_bucket=None):
if same_bucket is None:
return Array(list(set(self)))
else:
removes = []
for lhs, rhs in zip(self, self[1:]):
if same_bucket(lhs, rhs):
removes.append(lhs)
for remove in removes:
self.remove(remove)
return self
def get(self, index, default=None):
try:
return self[index]
except IndexError:
return default
def push(self, value):
self.append(value)
return self
def partition(self, f):
return Array(list(filter(f, self))), Array(
list(filter(lambda x: not f(x), self))
)
def __mul__(self, n):
return then__(list.__mul__(self, n), Array)
def __getitem__(self, index_or_slice):
if isinstance(index_or_slice, slice):
return Array(list.__getitem__(self, index_or_slice))
elif isinstance(index_or_slice, NatMut) or isinstance(index_or_slice, IntMut):
return list.__getitem__(self, int(index_or_slice))
elif isinstance(index_or_slice, Range):
return Array(list.__getitem__(self, index_or_slice.into_slice()))
else:
return list.__getitem__(self, index_or_slice)
def type_check(self, t: type) -> bool:
if isinstance(t, list):
if len(t) != len(self):
return False
for (inner_t, elem) in zip(t, self):
if not contains_operator(inner_t, elem):
return False
return True
elif not hasattr(t, "__args__"):
return isinstance(self, t)
elem_t = t.__args__[0]
l = None if len(t.__args__) != 2 else t.__args__[1]
if l is not None and l != len(self):
return False
for elem in self:
if not contains_operator(elem_t, elem):
return False
return True
def update_nth(self, index, f):
self[index] = f(self[index])