/// @module std::core::vec
/// Method definitions for Vec<T> (Array).
///
/// Type-agnostic methods are defined via `extend Vec<T>`.
/// Numeric-only methods are defined via `trait NumericVec` + `impl NumericVec for Vec`.
/// Most methods have pure Shape implementations. Methods that need VM intrinsics
/// (pop, sort, groupBy) delegate to Rust PHF dispatch; the compiler self-call
/// guard prevents infinite recursion. Note: `len`/`isEmpty` are intentionally
/// NOT defined here — they would intercept dispatch and recurse on Vec<T>.
// -- Type-agnostic methods --------------------------------------------------
extend Vec<T> {
// NOTE: `len()` and `isEmpty()` are intentionally NOT defined here.
// `arr.len()` dispatches directly to the PHF handler (ARRAY_METHODS::handle_len_v2
// for Arc arrays; TYPED_INT_ARRAY_METHODS::len / TYPED_NUMBER_ARRAY_METHODS::len
// for v2 raw-ptr arrays via as_v2_typed_array). Defining `method len() -> int
// { self.len() }` here causes the extend-method to intercept dispatch and
// recurse infinitely (or, post self-call guard, produce garbage).
// Callers needing `isEmpty()` can write `arr.len() == 0` directly.
// --- Pure Shape implementations ---
method first() -> T { self[0] }
method last() -> T { self[self.len() - 1] }
method push(item: T) { self.push(item) } // ArrayPushLocal opcode (in-place)
method pop() -> T { self.pop() } // keep delegation — pop needs VM support
method reverse() -> Vec<T> {
let mut result = []
let mut i = self.len() - 1
while i >= 0 {
result.push(self[i])
i = i - 1
}
result
}
method clone() -> Vec<T> { self.slice(0, self.len()) }
method filter(predicate: (T) => bool) -> Vec<T> {
let mut result = []
for item in self {
if predicate(item) {
result.push(item)
}
}
result
}
method map<U>(f: (T) => U) -> Vec<U> {
let mut result = []
for item in self {
result.push(f(item))
}
result
}
method reduce<U>(f: (U, T) => U, init: U) -> U {
let mut acc = init
for item in self {
acc = f(acc, item)
}
acc
}
method find(predicate: (T) => bool) -> T {
for item in self {
if predicate(item) { return item }
}
}
method forEach(f: (T) => void) -> void {
for item in self { f(item) }
}
method some(predicate: (T) => bool) -> bool {
for item in self {
if predicate(item) { return true }
}
false
}
method every(predicate: (T) => bool) -> bool {
for item in self {
if !predicate(item) { return false }
}
true
}
method join(separator: string) -> string {
let mut result = ""
for i in 0..self.len() {
if i > 0 { result = result + separator }
result = result + self[i].toString()
}
result
}
method slice(start: int, end: int) -> Vec<T> {
let mut result = []
let mut i = start
while i < end && i < self.len() {
result.push(self[i])
i = i + 1
}
result
}
method take(n: int) -> Vec<T> { self.slice(0, n) }
method drop(n: int) -> Vec<T> { self.slice(n, self.len()) }
method flatten() -> Vec<T> {
let mut result = []
for item in self {
for sub in item {
result.push(sub)
}
}
result
}
method unique() -> Vec<T> {
let mut result = []
for item in self {
if !result.includes(item) {
result.push(item)
}
}
result
}
method concat(other: Vec<T>) -> Vec<T> {
let mut result = []
for item in self { result.push(item) }
for item in other { result.push(item) }
result
}
method indexOf(value: T) -> int {
for i in 0..self.len() {
if self[i] == value { return i }
}
-1
}
method sort(cmp: (T, T) => number) -> Vec<T> { self.sort(cmp) } // keep Rust delegation
method includes(value: T) -> bool {
for item in self {
if item == value { return true }
}
false
}
method findIndex(predicate: (T) => bool) -> int {
for i in 0..self.len() {
if predicate(self[i]) { return i }
}
-1
}
method flatMap<U>(f: (T) => Vec<U>) -> Vec<U> {
let mut result = []
for item in self {
for sub in f(item) {
result.push(sub)
}
}
result
}
method groupBy<K>(key_fn: (T) => K) -> Vec<K> { self.groupBy(key_fn) } // keep Rust delegation (HashMap needed)
method sortBy(key_fn: (T) => number) -> Vec<T> {
self.sort(|a, b| {
let ka = key_fn(a)
let kb = key_fn(b)
if ka < kb { -1 }
else if ka > kb { 1 }
else { 0 }
})
}
}
// -- Numeric-only methods ---------------------------------------------------
trait NumericVec {
sum(): number,
avg(): number,
mean(): number,
min(): number,
max(): number,
std(): number,
variance(): number,
dot(other: Vec<number>): number,
norm(): number,
normalize(): Vec<number>,
cumsum(): Vec<number>,
diff(): Vec<number>,
abs(): Vec<number>,
}
impl NumericVec for Vec {
method sum() -> number { self.sum() }
method avg() -> number { self.avg() }
method mean() -> number { self.mean() }
method min() -> number { self.min() }
method max() -> number { self.max() }
method std() -> number { self.std() }
method variance() -> number { self.variance() }
method dot(other: Vec<number>) -> number { self.dot(other) }
method norm() -> number { self.norm() }
method normalize() -> Vec<number> { self.normalize() }
method cumsum() -> Vec<number> { self.cumsum() }
method diff() -> Vec<number> { self.diff() }
method abs() -> Vec<number> { self.abs() }
}