Skip to content

Commit 1f14309

Browse files
committed
feat: add underscore base class
1 parent a5dcf2e commit 1f14309

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

src/UnderscoreBase.php

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
<?php
2+
3+
namespace Ahc\Underscore;
4+
5+
class UnderscoreBase implements \ArrayAccess, \Countable, \IteratorAggregate, \JsonSerializable
6+
{
7+
const VERSION = '0.0.1';
8+
9+
/** @var array The array manipulated by this Underscore instance */
10+
protected $data;
11+
12+
/**
13+
* Constructor.
14+
*
15+
* @param array|mixed $data.
16+
*/
17+
public function __construct($data = [])
18+
{
19+
$this->data = \is_array($data) ? $data : $this->asArray($data);
20+
}
21+
22+
/**
23+
* Get the underlying array data.
24+
*
25+
* @param string|int|null $index
26+
*
27+
* @return mixed
28+
*/
29+
public function get($index = null)
30+
{
31+
if (null === $index) {
32+
return $this->data;
33+
}
34+
35+
return $this->data[$index];
36+
}
37+
38+
/**
39+
* Get data as array.
40+
*
41+
* @param mixed $data
42+
*
43+
* @return array
44+
*/
45+
public function asArray($data)
46+
{
47+
if (\is_array($data)) {
48+
return $data;
49+
}
50+
51+
if ($data instanceof static) {
52+
return $data->get();
53+
}
54+
55+
// @codeCoverageIgnoreStart
56+
if ($data instanceof \Traversable) {
57+
return \iterator_to_array($data);
58+
}
59+
// @codeCoverageIgnoreEnd
60+
61+
if ($data instanceof \JsonSerializable) {
62+
return $data->jsonSerialize();
63+
}
64+
65+
if (\method_exists($data, 'toArray')) {
66+
return $data->toArray();
67+
}
68+
69+
return (array) $data;
70+
}
71+
72+
/**
73+
* Flatten a multi dimension array to 1 dimension.
74+
*
75+
* @param array $array
76+
*
77+
* @return array
78+
*/
79+
public function flat($array, &$flat = [])
80+
{
81+
foreach ($array as $value) {
82+
if ($value instanceof static) {
83+
$value = $value->get();
84+
}
85+
86+
if (\is_array($value)) {
87+
$this->flat($value, $flat);
88+
} else {
89+
$flat[] = $value;
90+
}
91+
}
92+
93+
return $flat;
94+
}
95+
96+
/**
97+
* Negate a given truth test callable.
98+
*
99+
* @param callable $fn
100+
*
101+
* @return callable
102+
*/
103+
protected function negate(callable $fn)
104+
{
105+
return function () use ($fn) {
106+
return !\call_user_func_array($fn, \func_get_args());
107+
};
108+
}
109+
110+
/**
111+
* Get a value generator callable.
112+
*
113+
* @param callable|string|null $fn
114+
*
115+
* @return callable
116+
*/
117+
protected function valueFn($fn)
118+
{
119+
if (\is_callable($fn)) {
120+
return $fn;
121+
}
122+
123+
return function ($value) use ($fn) {
124+
if (null === $fn) {
125+
return $value;
126+
}
127+
128+
$value = \array_column([$value], $fn);
129+
130+
return $value ? $value[0] : null;
131+
};
132+
}
133+
134+
/**
135+
* {@inheritdoc}
136+
*/
137+
public function offsetExists($index)
138+
{
139+
return \array_key_exists($index, $this->data);
140+
}
141+
142+
/**
143+
* {@inheritdoc}
144+
*/
145+
public function offsetGet($index)
146+
{
147+
return $this->data[$index];
148+
}
149+
150+
/**
151+
* {@inheritdoc}
152+
*/
153+
public function offsetSet($index, $value)
154+
{
155+
$this->data[$index] = $value;
156+
}
157+
158+
/**
159+
* {@inheritdoc}
160+
*/
161+
public function offsetUnset($index)
162+
{
163+
unset($this->data[$index]);
164+
}
165+
166+
/**
167+
* {@inheritdoc}
168+
*/
169+
public function count()
170+
{
171+
return \count($this->data);
172+
}
173+
174+
/**
175+
* {@inheritdoc}
176+
*/
177+
public function getIterator()
178+
{
179+
return new \ArrayIterator($this->data);
180+
}
181+
182+
/**
183+
* {@inheritdoc}
184+
*/
185+
public function jsonSerialize()
186+
{
187+
return $this->data;
188+
}
189+
190+
/**
191+
* {@inheritdoc}
192+
*/
193+
public function __toString()
194+
{
195+
return \json_encode($this->data);
196+
}
197+
198+
public static function _($data)
199+
{
200+
return new static($data);
201+
}
202+
}

0 commit comments

Comments
 (0)