<?php

namespace App\Helper;


use Illuminate\Support\Collection;

/**
 * 数组类函数
 * Class Arrays
 * @package App\Helper
 * @author zbj
 * @date 2023/4/15
 */
class Arr extends \Illuminate\Support\Arr
{
    /**
     * 把返回的数据集转换成Tree
     * @param $list
     * @param string $pk
     * @param string $pid
     * @param string $child
     * @param int $root
     * @return array
     * @author zbj
     * @date 2023/4/13
     */
    public static function listToTree($list, $pk = 'id', $pid = 'pid', $child = 'children', $root = 0)
    {
        // 创建Tree
        $tree = array();
        if (is_array($list)) {
            // 创建基于主键的数组引用
            $refer = array();
            foreach ($list as $key => $data) {
                $refer[$data[$pk]] = &$list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $parentId = $data[$pid];
                if ($root == $parentId) {
                    $tree[] = &$list[$key];
                } else {
                    if (isset($refer[$parentId])) {
                        $parent = &$refer[$parentId];
                        $parent[$child][] = &$list[$key];
                    }
                }
            }
        }
        return $tree;
    }


    /**
     * 分隔字符串成数组并按照指定的函数过滤数组
     * @param string $string
     * @param string $filters
     * @param string $delimiter
     * @return array|false|string[]
     * @author zbj
     * @date 2023/4/13
     */
    public static function splitFilterToArray($string, $filters = 'trim', $delimiter = ',')
    {
        if (!$string) {
            return [];
        }
        $data = !is_array($string) ? explode($delimiter, $string) : $string;
        $filters = explode(',', $filters);
        if (!$filters) {//没有值或者没有过滤函数
            return $data;
        }
        //过滤
        foreach ($filters as $fun) {
            if (!function_exists($fun)) {
                continue;
            }
            $data = array_map($fun, $data);
        }

        return $data;
    }


    /**
     * 只保留指定的key  最多支持二维数组
     * @param array $rows 需要过滤的数组
     * @param array $keepKeys 需要保留的键名
     * @return array|array[]|mixed
     * @author zbj
     * @date 2023/4/15
     */
    public static function twoKeepKeys(array $rows, array $keepKeys)
    {

        if (!$rows || !$keepKeys) {
            return $rows;
        }

        //第一维有字符串键名 就过滤第一维
        $signle = false;
        $keys = array_keys($rows);
        foreach ($keys as $k) {
            if (!is_numeric($k)) {
                $signle = true;
                $rows = [$rows];
                break;
            }
        }

        //将数组将非法的键去掉
        $rows = array_map(function ($item) use ($keepKeys) {
            if (!is_array($item)) {
                return $item;
            }

            $illegalKeys = array_diff(array_keys($item), $keepKeys);//获取非法键名
            if ($illegalKeys) {
                foreach ($illegalKeys as $key) {
                    unset($item[$key]);
                }
            }

            return $item;
        }, $rows);

        return $signle ? $rows[0] : $rows;
    }


    /**
     * 数组转字符串
     * @param $arr
     * @return string
     * @author zbj
     * @date 2023/4/17
     */
    public static function a2s($arr): string
    {
        return json_encode($arr, JSON_UNESCAPED_UNICODE);
    }


    /**
     * 字符串转数组
     * @param $str
     * @return array|mixed
     * @author zbj
     * @date 2023/4/17
     */
    public static function s2a($str)
    {
        if (is_array($str)) {
            return $str;
        }
        return is_object($str) ? (array)$str : json_decode($str, true);
    }


    /**
     * 数组转set形式字符串
     * @param $arr
     * @param string $format
     * @return string
     * @author zbj
     * @date 2023/4/17
     */
    public static function arrToSet($arr, string $format = 'intval'): string
    {
        $arr = array_unique(array_filter(Arr::splitFilterToArray($arr, $format, ',')));
        return $arr ? implode(',', $arr) : '';
    }

    /**
     * set形式字符串转数组
     * @param $str
     * @param string $format
     * @return array
     * @author zbj
     * @date 2023/4/17
     */
    public static function setToArr($str, string $format = 'intval')
    {
        if (is_string($str)) {
            return Arr::splitFilterToArray($str, $format, ',');
        }
        return $str ?: [];
    }


    /**
     * 将数组设置成某个键的值
     * @param $arr
     * @param $key
     * @return array
     * @author zbj
     * @date 2023/5/16
     */
    public static function setValueToKey($arr, $key)
    {
        $data = [];
        if (!$arr) {
            return $data;
        }
        foreach ($arr as $v) {
            $data[$v[$key]] = $v;
        }

        if ($arr instanceof Collection) {
            $data = new Collection($data);
        }
        return $data;
    }

    /**
     * 根据列表查找指定id下的所有子id
     * @param $dataArray
     * @param $parentId
     * @param $resultArray
     * @author zbj
     * @date 2023/10/17
     */
    public static function findChildIds($dataArray, $parentId, &$resultArray) {
        foreach ($dataArray as $value) {
            if ($value['pid'] == $parentId) {
                $resultArray[] = $value['id'];
                self::findChildIds($dataArray, $value['id'], $resultArray);
            }
        }
    }
}