1: <?php
2: /**
3: * @filesource Kotchasan/ArrayTool.php
4: *
5: * @copyright 2016 Goragod.com
6: * @license http://www.kotchasan.com/license/
7: *
8: * @see http://www.kotchasan.com/
9: */
10:
11: namespace Kotchasan;
12:
13: /**
14: * Array function class.
15: *
16: * @author Goragod Wiriya <admin@goragod.com>
17: *
18: * @since 1.0
19: */
20: class ArrayTool
21: {
22: /**
23: * คืนค่ารายการที่มีคอลัมน์ตามที่กำหนด.
24: *
25: * @assert (array(array('id' => 1, 'name' => 'one'), array('id' => 2, 'name' => 'two'), array('id' => 3, 'name' => 'three')), 'name') [==] array(0 => 'one', 1 => 'two', 2 => 'three')
26: * @assert (array(array('id' => 1, 'name' => 'one'), array('id' => 2, 'name' => 'two'), array('id' => 3, 'name' => 'three')), 'name', 'id') [==] array(1 => 'one', 2 => 'two', 3 => 'three')
27: *
28: * @param array $array
29: * @param string $column_key ชื่อคอลัมน์ที่ต้องการ
30: * @param mixed $index_key null คืนค่า index ของ $array, string คืนค่า index จากคอลัมน์ที่กำหนด
31: *
32: * @return array
33: */
34: public static function columns($array, $column_key, $index_key = null)
35: {
36: $result = array();
37: if ($index_key == null) {
38: foreach ($array as $i => $item) {
39: if (isset($item[$column_key])) {
40: $result[$i] = $item[$column_key];
41: }
42: }
43: } else {
44: foreach ($array as $i => $item) {
45: if (isset($item[$column_key])) {
46: $result[$item[$index_key]] = $item[$column_key];
47: }
48: }
49: }
50:
51: return $result;
52: }
53:
54: /**
55: * ลบรายการที่ id สามารถลบได้หลายรายการโดยคั่นแต่ละรายการด้วย ,
56: * รักษาคีย์ของรายการเดิมไว้
57: * คืนค่า array ใหม่หลังจากลบแล้ว.
58: *
59: * @assert (array(0, 1, 2, 3, 4, 5), '0,2') [==] array(1 => 1, 3 => 3, 4 => 4, 5 => 5)
60: *
61: * @param array $array
62: * @param string $ids รายการที่ต้องการลบ 1 หรือ 1,2,3
63: *
64: * @return array
65: */
66: public static function delete($array, $ids)
67: {
68: $temp = array();
69: $ids = explode(',', $ids);
70: foreach ($array as $k => $v) {
71: if (!in_array($k, $ids)) {
72: $temp[$k] = $v;
73: }
74: }
75:
76: return $temp;
77: }
78:
79: /**
80: * ฟังก์ชั่นแยก $key และ $value ออกจาก array รองรับข้อมูลรูปแบบแอเรย์ย่อยๆ.
81: *
82: * @param array $array array('key1' => 'value1', 'key2' => 'value2', array('key3' => 'value3', 'key4' => 'value4'))
83: * @param array $keys คืนค่า $key Array ( [0] => key1 [1] => key2 [2] => key3 [3] => key4 )
84: * @param array $values คืนค่า $value Array ( [0] => value1 [1] => value2 [2] => value3 [3] => value4 )
85: */
86: public static function extract($array, &$keys, &$values)
87: {
88: foreach ($array as $key => $value) {
89: if (is_array($value)) {
90: self::extract($array[$key], $keys, $values);
91: } else {
92: $keys[] = $key;
93: $values[] = $value;
94: }
95: }
96: }
97:
98: /**
99: * เลือกรายการ array ที่มีข้อมูลที่กำหนด.
100: *
101: * @assert (array('one', 'One', 'two'), 'one') [==] array('one', 'One')
102: *
103: * @param array $array
104: * @param string $search ข้อมูลที่ต้องการ
105: *
106: * @return array
107: */
108: public static function filter($array, $search)
109: {
110: if ($search == '') {
111: return $array;
112: } else {
113: $result = array();
114: foreach ($array as $key => $value) {
115: if (stripos(self::toString(' ', $value), $search) !== false) {
116: $result[$key] = $value;
117: }
118: }
119:
120: return $result;
121: }
122: }
123:
124: /**
125: * คืนค่าข้อมูลแอเรย์ที่ $key
126: * ไม่พบคืนค่า $default
127: *
128: * @assert (array('one', 'two', 'three'), 0, '') [==] 'one'
129: * @assert (array('one', 'two', 'three'), 4, '') [==] ''
130: *
131: * @param array $array
132: * @param string|int $key
133: * @param mix $array
134: *
135: * @return mix
136: */
137: public static function get($array, $key, $default = '')
138: {
139: return isset($array[$key]) ? $array[$key] : $default;
140: }
141:
142: /**
143: * อ่านคีย์รายการแรก
144: * ไม่พบ คืนค่า null
145: *
146: * @param array $array
147: *
148: * @return mixed
149: */
150: public static function getFirstKey($array)
151: {
152: foreach ($array as $key => $value) {
153: return $key;
154: }
155:
156: return null;
157: }
158:
159: /**
160: * แทรกข้อมูลลงในแอเรย์ ข้อมูลที่จะนำมาแทรกอยู่ถัดไป
161: * ถ้าไม่พบ $find ข้อมูลจะแทรกรายการสุดท้าย.
162: *
163: * @assert (array('one' => 1, 'two' => 2), 'two', 'three', 3) [==] array('one' => 1, 'two' => 2, 'three' => 3)
164: * @assert (array(1 => 'one', 2 => 'two'), 2, 3, 'three') [==] array(1 => 'one', 2 => 'two', 3 => 'three')
165: * @assert (array(1 => 'one', 2 => 'two'), 3, 3, 'three') [==] array(1 => 'one', 2 => 'two', 3 => 'three')
166: *
167: * @param array $source แอเรย์ต้นฉบับ
168: * @param int|string $find คีย์ของแอเรย์ต้นฉบับจุดที่จะแทรก ข้อมูลต้องเป็นชนิดเดียวกันกับคีย์ของแอเรย์ต้นฉบับ
169: * @param int|string $key คีย์ของข้อมูลที่จะนำมาแทรก
170: * @param mixed $value ข้อมูลที่จะนำมาแทรก
171: *
172: * @return array
173: */
174: public static function insertAfter($source, $find, $key, $value)
175: {
176: $result = array();
177: foreach ($source as $k => $v) {
178: $result[$k] = $v;
179: if ($find && $find === $k) {
180: $result[$key] = $value;
181: $find = null;
182: }
183: }
184: if ($find !== null) {
185: $result[$key] = $value;
186: }
187:
188: return $result;
189: }
190:
191: /**
192: * แทรกข้อมูลลงในแอเรย์ ข้อมูลที่จะนำมาแทรกอยู่ก่อน
193: * ถ้าไม่พบ $find ข้อมูลจะแทรกรายการสุดท้าย.
194: *
195: * @assert (array('one' => 1, 'three' => 3), 'three', 'two', 2) [==] array('one' => 1, 'two' => 2, 'three' => 3)
196: * @assert (array(1 => 'one', 3 => 'three'), 3, 2, 'two') [==] array(1 => 'one', 2 => 'two', 3 => 'three')
197: * @assert (array(1 => 'one', 3 => 'three'), 2, 2, 'two') [==] array(1 => 'one', 3 => 'three', 2 => 'two')
198: *
199: * @param array $source แอเรย์ต้นฉบับ
200: * @param int|string $find คีย์ของแอเรย์ต้นฉบับจุดที่จะแทรก ข้อมูลต้องเป็นชนิดเดียวกันกับคีย์ของแอเรย์ต้นฉบับ
201: * @param int|string $key คีย์ของข้อมูลที่จะนำมาแทรก
202: * @param mixed $value ข้อมูลที่จะนำมาแทรก
203: *
204: * @return array
205: */
206: public static function insertBefore($source, $find, $key, $value)
207: {
208: $result = array();
209: foreach ($source as $k => $v) {
210: if ($find && $find === $k) {
211: $result[$key] = $value;
212: $find = null;
213: }
214: $result[$k] = $v;
215: }
216: if ($find !== null) {
217: $result[$key] = $value;
218: }
219:
220: return $result;
221: }
222:
223: /**
224: * ฟังก์ชั่นรวมแอเรย์ รักษาแอเรย์ต้นฉบับไว้ และแทนที่ข้อมูลด้วยข้อมูลใหม่.
225: *
226: * @assert (array(1 => 1, 2 => 2, 3 => 'three'), array(1 => 'one', 2 => 'two')) [==] array(1 => 'one', 2 => 'two', 3 => 'three')
227: *
228: * @param array $source แอเร์ยต้นฉบับ
229: * @param array|object $replace ข้อมูลที่จะนำมาแทนที่ลงในแอเร์ยต้นฉบับ
230: *
231: * @return array
232: */
233: public static function replace($source, $replace)
234: {
235: foreach ($replace as $key => $value) {
236: $source[$key] = $value;
237: }
238:
239: return $source;
240: }
241:
242: /**
243: * ค้นหาแอเรย์ จากคอลัมน์
244: * คืนค่าทุกรายการที่พบ รักษา index ตาม array ของต้นฉบับและ คืนค่าแอเรย์ว่างถ้าไม่พบ.
245: *
246: * @assert (array(array('id' => 1, 'name' => 'one'), array('id' => 2, 'name' => 'two'), array('id' => 3, 'name' => 'one')), 'name', 'one') [==] array(0 => array('id' => 1, 'name' => 'one'), 2 => array('id' => 3, 'name' => 'one'))
247: * @assert (array(array('id' => 1, 'name' => 'one'), array('id' => 2, 'name' => 'two'), array('id' => 3, 'name' => 'one')), 'id', 'one') [==] array()
248: *
249: * @param array $input ข้อมูลแอเรย์
250: * @param mixed $key คอลัมน์ที่ต้องการค้นหา
251: * @param mixed $search ข้อความค้นหา
252: *
253: * @return array
254: */
255: public static function search($input, $key, $search)
256: {
257: $result = array();
258: foreach ($input as $i => $values) {
259: if (isset($values[$key]) && $values[$key] == $search) {
260: $result[$i] = $values;
261: }
262: }
263:
264: return $result;
265: }
266:
267: /**
268: * ตัดแอเรย์ตั้งแต่เริ่มต้นจนถึงตำแหน่งที่กำหนด
269: * คืนค่าแอเรย์ถัดจากรายการที่ตัด ไม่พบคืนค่าเดิม
270: *
271: * @assert (array('one' => 1, 'two' => 2, 'three' => 3), 'two') [==] array('three' => 3)
272: * @assert (array('one' => 1, 'two' => 2, 'three' => 3), 1) [==] array('one' => 1, 'two' => 2, 'three' => 3)
273: *
274: * @param array $source แอเรย์ต้นฉบับ
275: * @param string|int $key คีย์ของ $source ตำแหน่งที่ต้องการตัด
276: *
277: * @return array
278: */
279: public static function shift($source, $key)
280: {
281: $result = array();
282: foreach ($source as $k => $v) {
283: if ($k == $key) {
284: $result = array();
285: } else {
286: $result[$k] = $v;
287: }
288: }
289:
290: return $result;
291: }
292:
293: /**
294: * ฟังก์ชั่น เรียงลำดับ array ตามชื่อฟิลด์.
295: *
296: * @assert (array(array('id' => 2, 'value' => 'two'), array('id' => 3, 'value' => 'three'), array('id' => 1, 'value' => 'one'))) [==] array(array('id' => 1, 'value' => 'one'), array('id' => 2, 'value' => 'two'), array('id' => 3, 'value' => 'three'))
297: *
298: * @param array $array แอเรย์ที่ต้องการเรียงลำดับ
299: * @param string $sort_key (optional) คืย์ของ $array ที่ต้องการในการเรียง (default id)
300: * @param bool $sort_desc true=เรียงจากมากไปหาน้อย, false=เรียงจากน้อยไปหามาก (default false)
301: *
302: * @return array
303: */
304: public static function sort($array, $sort_key = 'id', $sort_desc = false)
305: {
306: if (!empty($array)) {
307: $temp_array[key($array)] = array_shift($array);
308: foreach ($array as $key => $val) {
309: $offset = 0;
310: $found = false;
311: foreach ($temp_array as $tmp_val) {
312: $v1 = isset($val[$sort_key]) ? strtolower(self::toString('', $val[$sort_key])) : '';
313: $v2 = isset($tmp_val[$sort_key]) ? strtolower(self::toString('', $tmp_val[$sort_key])) : '';
314: if (!$found && $v1 > $v2) {
315: $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array($key => $val), array_slice($temp_array, $offset));
316: $found = true;
317: }
318: ++$offset;
319: }
320: if (!$found) {
321: $temp_array = array_merge($temp_array, array($key => $val));
322: }
323: }
324: if ($sort_desc) {
325: return $temp_array;
326: } else {
327: return array_reverse($temp_array);
328: }
329: }
330:
331: return $array;
332: }
333:
334: /**
335: * แปลงแอเรย์ $array เป็น string คั่นด้วย $glue.
336: *
337: * @assert ('|', array('a' => 'A', 'b' => array('b', 'B'), 'c' => array('c' => array('c', 'C')))) [==] "A|b|B|c|C"
338: *
339: * @param string $glue ตัวคั่นข้อมูล
340: * @param array $array แอเรย์ที่ต้องการนำมาเชื่อม
341: *
342: * @return string
343: */
344: public static function toString($glue, $array)
345: {
346: if (is_array($array)) {
347: $result = array();
348: foreach ($array as $key => $value) {
349: if (is_array($value)) {
350: $result[] = self::toString($glue, $value);
351: } else {
352: $result[] = $value;
353: }
354: }
355:
356: return implode($glue, $result);
357: } else {
358: return $array;
359: }
360: }
361:
362: /**
363: * ฟังก์ชั่นแปลงข้อความ serialize เป็นแอเรย์
364: * และรวมข้อมูลเข้ากับ $source.
365: *
366: * @assert ('') [==] array()
367: * @assert (serialize(array(1, 2, 3))) [==] array(1, 2, 3)
368: * @assert (serialize(array(1 => 'One', 2 => 'Two', 3 => 'Three')), array(3 => 3, 4 => 'Four'), true) [==] array(3 => 'Three', 4 => 'Four', 1 => 'One', 2 => 'Two')
369: * @assert (serialize(array(1 => 'One', 2 => 'Two', 3 => 'Three')), array(3 => 3, 4 => 'Four'), false) [==] array(3 => 3, 4 => 'Four', 1 => 'One', 2 => 'Two')
370: *
371: * @param string $str ข้อมูล serialize
372: * @param array $source ข้อมูลตั้งต้น ถ้าใช้ฟังก์ชั่นนี้ในการแปลงข้อมูล ค่านี้จะเป็นแอเรย์ว่าง (ค่าเริ่มต้น)
373: * @param bool $replace true (default) แทนที่ข้อมูลเดิม, false เก็บข้อมูลเดิมไว้
374: *
375: * @return array
376: */
377: public static function unserialize($str, $source = array(), $replace = true)
378: {
379: try {
380: $datas = unserialize($str);
381: if (is_array($datas)) {
382: foreach ($datas as $key => $value) {
383: if ($replace || !isset($source[$key])) {
384: $source[$key] = $value;
385: }
386: }
387: }
388: } catch (\Throwable $th) {
389: }
390:
391: return $source;
392: }
393:
394: /**
395: * ตรวจสอบว่ามี $needle ใน $haystack หรือไม่
396: * ถ้ามีคืนค่า true ถ้าไม่มีคืนค่า false
397: *
398: * @assert (array(1, 2), array(1, 2)) [==] true
399: * @assert (array(2), array(1, 2, 3)) [==] true
400: * @assert (array(1, 2), array(3, 4)) [==] false
401: * @assert (array(), array(3, 4)) [==] false
402: * @assert (array(), array()) [==] false
403: *
404: * @param array $needle แอเรย์ที่ต้องการตรวจสอบ
405: * @param array $haystack แอเรย์ต้นฉบับ
406: *
407: * @return bool
408: */
409: public static function in_array($needle, $haystack)
410: {
411: foreach ($needle as $v) {
412: if (in_array($v, $haystack)) {
413: return true;
414: }
415: }
416:
417: return false;
418: }
419: }
420: