set($_); return $r; } function _a($a = array()) { $r = new _array(); return $r->set($a); } function _w($str, $delim = ' ') { $r = new _array(); return $r->set(explode($delim, $str)); } class _array implements ArrayAccess, Countable, IteratorAggregate { function __construct() { $this->a = func_get_args(); } function __toString() { return implode(', ', $this->_flatten($this->a)); } function __clone() { return $this->_new($this->a); } function offsetExists($k) { return isset($this->a[$k]); } function offsetGet($k) { return $this->a[$k]; } function offsetSet($k, $v) { strlen($k) ? ($this->a[$k] = $v) : ($this->a[] = $v); } function offsetUnset($k) { unset($this->a[$k]); } function getIterator() { return new ArrayIterator($this->a); } function count($recurse = false) { return $recurse ? $this->_count($this->a) : count($this->a); } function copy() { return clone $this; } function a($recurse = false) { if(!$recurse) return $this->a; $b = array(); foreach($this->a as $k => $v) $b[$k] = ($v instanceof self) ? $v->a(true) : $v; return $b; } function to_array($recurse = false) { return $this->a($recurse); } function values() { return $this->_new(array_values($this->a)); } function keys() { return $this->_new(array_keys($this->a)); } function set($array) { $this->a = is_array($array) ? $array : array($array); return $this; } function from_string($str, $len = 1) { $this->a = str_split($str, $len); return $this; } function from_text($str) { $this->a = array_filter(array_map('trim', explode("\n", $str))); return $this; } function from_call($func) { $_ = func_get_args(); array_shift($_); $b = array(); while($v = call_user_func_array($func, $_)) $b[] = $v; $this->a = $b; return $this; } function e($key = null) { return is_null($key) ? reset($this->a) : (isset($this->a[$key]) ? $this->a[$key] : null); } function item($key = null) { return is_null($key) ? reset($this->a) : (isset($this->a[$key]) ? $this->a[$key] : null); } function n($offset = 0) { $b = array_slice($this->a, $offset, 1); return count($b) ? reset($b) : null; } function max() { return max($this->a); } function min() { return min($this->a); } function rand() { return $this->a[array_rand($this->a)]; } function find($value, $strict = false) { $b = array_search($value, $this->a, $strict); return $b === false ? null : $b; } function index($value, $strict = false) { $b = array_search($value, $this->a); return $b === false ? -1 : array_search($b, array_keys($this->a), true); } function contains($value, $strict = false) { return in_array($value, $this->a, $strict); } function map($func) { $_ = func_get_args(); $b = array(); if(count($_) == 1) $b = array_map($func, $this->a); else foreach($this->a as $k => $v) { $_[0] = $v; $b[$k] = call_user_func_array($func, $_); } return $this->_new($b); } function each($func) { $_ = func_get_args(); array_shift($_); $b = array(); foreach($this->a as $k => $v) { $b[$k] = call_user_func_array(array($v, $func), $_); } return $this->_new($b); } function rmap($func) { $_ = func_get_args(); $b = $this->_rmap($this->a, $_); return $this->_new($b); } function kmap($func) { $_ = func_get_args(); array_unshift($_, ''); $b = array(); foreach($this->a as $k => $v) { $_[0] = $v; $_[1] = $k; $b[$k] = call_user_func_array($func, $_); } return $this->_new($b); } function filter($func = null) { $_ = func_get_args(); return $this->_new($this->_filter($this->a, $_)); } function select($func = null) { $_ = func_get_args(); return $this->_new($this->_filter($this->a, $_)); } function reject($func = null) { $_ = func_get_args(); $b = $this->_filter($this->a, $_); return $this->_new(array_diff($this->a, $b)); } function apply($func, $args) { $_ = func_get_args(); array_splice($_, 0, 2); return call_user_func_array( array($this, $func), array_merge($this->_ary($args), $_) ); } function tab($func) { $b = $this->a; $c = array_shift($b); if(!$c instanceof self) $c = $this->_new($c); return call_user_func_array(array($c, $func), $b); } function remove() { $_ = func_get_args(); return $this->_new(array_diff($this->a, $_)); } function grep($regexp, $matching = true) { $b = preg_grep($regexp, $this->a, $matching ? 0 : PREG_GREP_INVERT); return $this->_new($b); } function inject($func, $memo = null) { $_ = func_get_args(); foreach($this->a as $v) { $_[0] = $memo; $_[1] = $v; $memo = call_user_func_array($func, $_); } return $memo; } function reduce($func, $memo = null) { $_ = func_get_args(); foreach($this->a as $v) { $_[0] = $memo; $_[1] = $v; $memo = call_user_func_array($func, $_); } return $memo; } const NORMAL = 1; const NUMERIC = 2; const ALPHA = 3; const NOCASE = 4; const NATURAL = 5; const NATCASE = 6; function sort($param = null) { $b = $this->a; if(func_num_args() == 0) { sort($b); } else if(is_callable($param)) { usort($b, $param); } else { $param = (int) $param; switch(abs($param)) { case self::NUMERIC: sort($b, SORT_NUMERIC); break; case self::ALPHA: sort($b, SORT_STRING); break; case self::NOCASE: usort($b, 'strcasecmp'); break; case self::NATURAL: natsort($b); break; case self::NATCASE: natcasesort($b); break; default: sort($b); break; } if($param < 0) $b = array_reverse($b); } return $this->_new(array_values($b)); } function natsort($param = null) { $c = self::NATURAL; if(intval($param) < 0) $c = -$c; return $this->sort($c); } function ksort($param = null) { $b = array(); foreach($this->keys()->sort($param) as $key) $b[$key] = $this->a[$key]; return $this->_new($b); } function slice($offset, $len = null) { switch(func_num_args()) { case 1: $b = array_slice($this->a, $offset); break; case 2: $b = array_slice($this->a, $offset, $len); break; } return $this->_new(array_values($b)); } function sub($from, $to = null) { if(func_num_args() == 1) { $b = array_slice($this->a, $from); } else { $c = count($this->a); if($from < 0) $from += $c; if($to < 0) $to += $c; $b = array_slice($this->a, $from, abs($to - $from + 1)); } return $this->_new(array_values($b)); } function splice($offset, $len = null, $ary = null) { $b = $this->a; switch(func_num_args()) { case 1: array_splice($b, $offset); break; case 2: array_splice($b, $offset, $len); break; case 3: array_splice($b, $offset, $len, $this->_ary($ary)); break; } return $this->_new($b); } function append($ary) { $b = $this->a; array_splice($b, count($b), 0, $this->_ary($ary)); return $this->_new($b); } function insert($ary, $pos = 0) { $b = $this->a; array_splice($b, $pos, 0, $this->_ary($ary)); return $this->_new($b); } function push() { $_ = func_get_args(); array_splice($this->a, count($this->a), 0, $_); return $this; } function unshift() { $_ = func_get_args(); array_splice($this->a, 0, 0, $_); return $this; } function pop() { return array_pop($this->a); } function shift() { return array_shift($this->a); } function union() { $_ = func_get_args(); return $this->_gcall('array_merge', $_)->unique(); } function intersect() { $_ = func_get_args(); return $this->_gcall('array_intersect', $_); } function diff() { $_ = func_get_args(); return $this->_gcall('array_diff', $_); } function zip() { $_ = func_get_args(); $_ = array_map(array($this, '_ary'), $_); $b = array(); foreach($this->a as $k => $v) { $q = array($v); foreach($_ as $arg) if(isset($arg[$k])) $q[] = $arg[$k]; $b[$k] = $q; } return $this->_new($b); } function pluck($key) { $b = array(); foreach($this->a as $v) { if(($v instanceof self) && isset($v->a[$key])) $b[] = $v->a[$key]; else if(is_array($v) && isset($v[$key])) $b[] = $v[$key]; } return $this->_new($b); } function combine($values) { $b = array(); $values = $this->_ary($values); foreach($this->a as $key) $b[$key] = array_shift($values); if(count($values)) $b = array_merge($b, $values); return $this->_new($b); } function flatten() { $b = $this->a; return $this->_new($this->_flatten($b)); } function pack($format) { $b = $this->a; array_unshift($b, $format); return call_user_func_array('pack', $b); } function join($delim = '') { return implode($delim, array_map('strval', $this->a)); } function stat($recurse = false) { if($recurse) { $stat = array(); $this->_stat($this->a, $stat); } else $stat = array_count_values($this->a); return $this->_new($stat); } function unique() { return $this->_new(array_unique($this->a)); } function reverse($preserve_keys = false) { return $this->_new(array_reverse($this->a, $preserve_keys)); } function flip() { return $this->_new(array_flip($this->a)); } function inspect() { return print_r($this->a, true); } protected $a = array(); protected function _new($ary) { $a = new self; $a->a = $ary; return $a; } protected function _stat($a, &$stat) { foreach($a as $e) { if(is_array($e)) $this->_stat($e, $stat); else if($e instanceof self) $this->_stat($e->a, $stat); else if(isset($stat[$e])) $stat[$e]++; else $stat[$e] = 1; } } protected function _count($a) { $c = 0; foreach($a as $e) { if(is_array($e)) $c += $this->_count($e); else if($e instanceof self) $c += $this->_count($e->a); else $c++; } return $c; } protected function _flatten($a) { $b = array(); foreach($a as $e) { if(is_array($e)) $b = array_merge($b, $this->_flatten($e)); else if($e instanceof self) $b = array_merge($b, $this->_flatten($e->values())); else $b[] = $e; } return $b; } protected function _gcall($func, $args) { $b = array_map(array($this, '_ary'), $args); array_unshift($b, $this->a); return $this->_new(call_user_func_array($func, $b)); } protected function _rmap($a, $args) { if($a instanceof self || is_array($a)) { $b = array(); foreach($a as $k => $v) $b[$k] = $this->_rmap($a[$k], $args); return $b; } $f = $args[0]; $args[0] = $a; return call_user_func_array($f, $args); } protected function _filter($a, $args) { $c = count($args); if($c == 0) return array_filter($a); if($c == 1) return array_filter($a, $args[0]); $b = array(); $func = $args[0]; foreach($a as $k => $v) { $args[0] = $v; if(call_user_func_array($func, $args)) $b[$k] = $v; } return $b; } protected function _ary($ary) { return $ary instanceof self ? $ary->a() : (is_array($ary) ? $ary : array($ary)); } } ?>