# Array / Collection Utilities — `arr.rs`

Inspired by **Laravel's Collection API** and **AdonisJS array helpers**. All functions are generic over `T` and use Rust's `Iterator` trait internally.

## 4.1 Transformation — `arr/ops.rs`

```rust
/// Map over a slice, collecting into Vec<U>
pub fn map<T, U>(arr: &[T], f: impl Fn(&T) -> U) -> Vec<U>

/// Filter with predicate
pub fn filter<T: Clone>(arr: &[T], f: impl Fn(&T) -> bool) -> Vec<T>

/// Filter-map (map + unwrap Some values)
pub fn filter_map<T, U>(arr: &[T], f: impl Fn(&T) -> Option<U>) -> Vec<U>

/// Reduce with accumulator
pub fn reduce<T, A>(arr: &[T], init: A, f: impl Fn(A, &T) -> A) -> A

/// Split into fixed-size chunks — Laravel: chunk()
pub fn chunk<T: Clone>(arr: &[T], size: usize) -> Vec<Vec<T>>

/// Flatten one level
pub fn flatten<T: Clone>(arr: &[Vec<T>]) -> Vec<T>

/// Flatten all levels (recursive via trait)
pub fn flatten_deep<T: Clone>(arr: &[serde_json::Value]) -> Vec<serde_json::Value>

/// Remove falsy/empty values — Laravel: compact()
pub fn compact<T: Default + PartialEq + Clone>(arr: &[T]) -> Vec<T>

/// Take first N items
pub fn take<T: Clone>(arr: &[T], n: usize) -> Vec<T>

/// Drop first N items
pub fn skip<T: Clone>(arr: &[T], n: usize) -> Vec<T>

/// Reverse
pub fn reverse<T: Clone>(arr: &[T]) -> Vec<T>

/// Zip two slices together
pub fn zip<A: Clone, B: Clone>(a: &[A], b: &[B]) -> Vec<(A, B)>
```

## 4.2 Query — `arr/query.rs`

```rust
pub fn first<T>(arr: &[T]) -> Option<&T>
pub fn last<T>(arr: &[T]) -> Option<&T>
pub fn get<T>(arr: &[T], index: usize) -> Option<&T>

/// Find first matching element
pub fn find<T>(arr: &[T], f: impl Fn(&T) -> bool) -> Option<&T>

/// Any element matches
pub fn some<T>(arr: &[T], f: impl Fn(&T) -> bool) -> bool

/// All elements match
pub fn every<T>(arr: &[T], f: impl Fn(&T) -> bool) -> bool

/// Check membership
pub fn contains<T: PartialEq>(arr: &[T], value: &T) -> bool

/// Group elements by key — Laravel: groupBy()
pub fn group_by<T, K>(arr: &[T], key_fn: impl Fn(&T) -> K) -> HashMap<K, Vec<T>>
where K: Eq + Hash, T: Clone

/// Index by unique key — Laravel: keyBy()
pub fn key_by<T, K>(arr: &[T], key_fn: impl Fn(&T) -> K) -> HashMap<K, T>
where K: Eq + Hash, T: Clone

/// Pluck a field from each item — Laravel: pluck()
pub fn pluck<T, U>(arr: &[T], extractor: impl Fn(&T) -> U) -> Vec<U>

/// where_in style filter
pub fn where_in<T: PartialEq + Clone>(arr: &[T], values: &[T]) -> Vec<T>

pub fn count<T>(arr: &[T]) -> usize
pub fn is_empty<T>(arr: &[T]) -> bool
pub fn is_not_empty<T>(arr: &[T]) -> bool
```

## 4.3 Set Operations — `arr/set.rs`

```rust
/// Remove duplicates (preserves order) — Laravel/AdonisJS: unique()
pub fn unique<T: PartialEq + Clone>(arr: &[T]) -> Vec<T>

/// Remove specific values — Laravel: without()
pub fn without<T: PartialEq + Clone>(arr: &[T], values: &[T]) -> Vec<T>

/// Merge two slices (no dedup)
pub fn merge<T: Clone>(a: &[T], b: &[T]) -> Vec<T>

/// Set intersection
pub fn intersect<T: PartialEq + Clone>(a: &[T], b: &[T]) -> Vec<T>

/// Set difference (a - b)
pub fn diff<T: PartialEq + Clone>(a: &[T], b: &[T]) -> Vec<T>

/// Sort with comparator
pub fn sort_by<T: Clone>(arr: &[T], cmp: impl Fn(&T, &T) -> std::cmp::Ordering) -> Vec<T>

/// Shuffle (requires feature = "random")
#[cfg(feature = "random")]
pub fn shuffle<T: Clone>(arr: &[T]) -> Vec<T>
```