一、排序
1、二维数组排序
主要思路是取出要用来的排序的字段,并以源数组键为建,对其进行相应排序后,对应回源数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| * 二维数组排序(保留键、值) * @param $arr array 排序数组 * @param $keys string 排序字段 * @param $order int 排序依据 0正序,1逆序 * @return $new_array array 返回排序后数组 */ function array_sort($arr,$keys,$order){ if(!is_array($arr)){ return false; } $keysvalue = array(); foreach($arr as $key=>$val){ $keysvalue[$key] = $val[$keys]; } if($order == 0){ asort($keysvalue); }else{ arsort($keysvalue); } reset($keysvalue); $new_array = array(); foreach($keysort as $key=>$val){ $new_array[$key] = $arr[$key]; } return $new_array; }
|
2、快速排序
前段时间遇到一个需要根据二位数组的中的多个维度进行排序的情况,于是将快速排序进行了一点改造,以支持多个维度的排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| * 快速排序(最多支持三个维度数据,可根据需要添加elseif语句,来扩充维度) * @param $arr array 排序数组 eg:$array = [[300,30,3],[300,40,2],[100,10,1],[100,10,2]]; * @param $order int 排序依据 0正序,1逆序 * @return $new_array array 返回排序后数组 */ function quickSort($arr){ if (count($arr) <= 1) { return $arr; } $key = $arr[0]; $left_arr = array(); $right_arr = array(); for ($i = 1; $i < count($arr); $i++) { if ($arr[$i] < $key) { $left_arr[] = $arr[$i]; } elseif ($arr[$i][0] < $key[0]) { $left_arr[] = $arr[$i]; } elseif ($arr[$i] == $key) { if ($arr[$i][1] < $key[1]) { $left_arr[] = $arr[$i]; } elseif ($arr[$i][1] == $key[1]) { if ($arr[$i][2] < $key[2]) { $left_arr[] = $arr[$i]; } } } else { $right_arr[] = $arr[$i]; } } $left_arr = quickSort($left_arr); $right_arr = quickSort($right_arr); return array_merge($left_arr,array($key),$right_arr); }
|
二、排序插入
同样是由于业务需要,在二分查找的基础上做了一个排序插入。
这个函数分两种情况:
一是如果插入的数据已经存在于当前数组,则不会重复插入,而是返回其所在位置。
二是如果插入的数据不存在则会将其插入顺序所在位置,并返回整个数组和其插入的位置,例如:向数组[1, 2, 3, 5]
中插入4
,则会返回[1, 2, 3, 4, 5, 'current'=>3]
这样的一个数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| * 排序插入 兼容 二分查找 * @param $array array Y 数组 * @param $v string Y 要找的值 * @param $low int N 查找范围的最小键值 * @param $high int N 范围的最大键值 * @return $array || $mid array || int 如果不存在返回插入且已排序数组 || 如果存在返回所在位置 */ function binInsert($array,$v,$low=0,$high=0){ if($high == 0){ $high = count($array); if($array[0] == $v){ return 0; } } $diff = $high - $low; if($diff == 0 || $diff == 1){ array_splice($array, $low+1, 0, $v); if($diff == 0){ $array['current'] = $low; }else{ $array['current'] = $low + 1; } return $array; } if($low<$high){ $mid = intval(($low+$high)/2); if($v == $array[$mid]){ return $mid; }elseif($v < $array[$mid]){ return binInsert($array, $v, $low, $mid); }else{ return binInsert($array, $v, $mid, $high); } } return 1; }
|
三、xml 转 array
同样是在工作中遇到的一个问题,就是从第三方取来一组数据,是xml格式的,处理起来头疼的很,于是将其转换为array,就可以随便处理了。其核心部分就是正则表示式/<(\w+)[^>]*>([\\x00-\\xFF]*?)<\\/\\1>/
。解释一下,<(\w+)[^>]*>
这一个部分匹配标签头;([\\x00-\\xFF]*?)
这一部分匹配标签内部所有内容,并且采用懒惰获取模式,即对后面的匹配模式<\\/\\1>
预查后匹配,否则会匹配到所有后面的元素;<\\/\\1>
这一部分匹配标签尾。
这其中有两部分匹配获取,及括号内的匹配项,会在下文的匹配结果(debug)中体现出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| * xml数据转换为array * @param $xml xml XML格式数据 * @param $repeatField string 同级重复标签项 * @return $arr array 转换后的数组 */ function xml_to_array($xml, $repeatField){ $regs = "/\s*/"; $xml = preg_replace($regs, '', $xml); $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*?)<\\/\\1>/"; if(preg_match_all($reg, $xml, $matches)) { $count = count($matches[0]); for($i = 0; $i < $count; $i++) { $subxml= $matches[2][$i]; if ($matches[1][$i] == $repeatField) { $key = $i; } else { $key = $matches[1][$i]; } if(preg_match($reg, $subxml)) { $arr[$key] = xml_to_array($subxml, $repeatField); }else{ $arr[$key] = $subxml; } } } return $arr; }
|
调用方法: xml_to_array($xml, ‘TempTable’)
数据源: 参考如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <NewDataSet> <TempTable> <nID>2880</nID> <EnterpriseID>8088</EnterpriseID> <EnterNO>100158</EnterNO> <CallID>136****6155201506012258055571</CallID> <CallerID>136****6155</CallerID> </TempTable> <TempTable> <nID>2879</nID> <EnterpriseID>8023</EnterpriseID> <EnterNO>101658</EnterNO> <CallID>186****5873201506012012599627</CallID> <CallerID>186****5873</CallerID> </TempTable> </NewDataSet> <Flag>Ok</Flag> <ReturnMsg>获取呼入记录成功!</ReturnMsg>
|
debug 数据
array[0]
是元数据,array[1]
是获取匹配一(\w+)
获取的内容,array[2]
是获取匹配二([\\x00-\\xFF]*?)
获取的内容。
如此一层层递归下去,一层层剥掉她们的外衣!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| array (size=3) 0 => array (size=3) 0 => string '<NewDataSet> <TempTable> <nID>2880</nID> <EnterpriseID>8088</EnterpriseID> <EnterNO>100158</EnterNO> <CallID>136****6155201506012258055571</CallID> <CallerID>136****6155</CallerID> </TempTable> <TempTable> <nID>2879</nID> <EnterpriseID>8023</EnterpriseID> <EnterNO>101658</EnterNO> <CallID>186****5873201506012012599627</CallID> <CallerID>186****5873</CallerID> </TempTable> </NewDataSet>' (length=373) 1 => string '<Flag>Ok</Flag>' (length=15) 2 => string '<ReturnMsg>获取呼入记录成功!</ReturnMsg>' (length=50) 1 => array (size=3) 0 => string 'NewDataSet' (length=10) 1 => string 'Flag' (length=4) 2 => string 'ReturnMsg' (length=9) 2 => array (size=3) 0 => string '<TempTable> <nID>2880</nID> <EnterpriseID>8088</EnterpriseID> <EnterNO>100158</EnterNO> <CallID>136****6155201506012258055571</CallID> <CallerID>136****6155</CallerID> </TempTable> <TempTable> <nID>2879</nID> <EnterpriseID>8023</EnterpriseID> <EnterNO>101658</EnterNO> <CallID>186****5873201506012012599627</CallID> <CallerID>186****5873</CallerID> </TempTable>' (length=348) 1 => string 'Ok' (length=2) 2 => string '获取呼入记录成功!' (length=27)
|
最终结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| array (size=3) 'NewDataSet' => array (size=2) 0 => array (size=5) 'nID' => string '2880' (length=4) 'EnterpriseID' => string '8088' (length=4) 'EnterNO' => string '100158' (length=6) 'CallID' => string '136****6155201506012258055571' (length=29) 'CallerID' => string '136****6155' (length=11) 1 => array (size=5) 'nID' => string '2879' (length=4) 'EnterpriseID' => string '8023' (length=4) 'EnterNO' => string '101658' (length=6) 'CallID' => string '186****5873201506012012599627' (length=29) 'CallerID' => string '186****5873' (length=11) 'Flag' => string 'Ok' (length=2) 'ReturnMsg' => string '获取呼入记录成功!' (length=27)
|