php数组相关操作函数片段
下面这些都是我在工作中用到的函数,现在整理下。
判断是否是一个数组
function _is_array($value){ if (is_array($value)) { return true; } else { if(is_object($value) && is_array(json_decode(json_encode($value),true))){ return true; } return (is_object($value) AND $value instanceof \Traversable);//实现这个接口对象可以foreach } }
清空数组
function _destruct_one($object){ if (_is_array($object)) { $length = count($object); while($length--){ array_splice($object,$length,1); } } return $object; } var_dump(_destruct_one([1,2,'d','key'=>'k'])); //array(0) {}
上面函数是清空整个数组内容,那么有时候需要清空数组中的空值或者false等值,我们需要重新写个函数。
下面这个函数可以递归过滤多维数组中 空白字符,负值,false,null
/*$arr 要删除的数组 * $trim 是否对字符trim操作 * $unsetEmptyArr 是否删除空的子数组 */ function _arrRemoveEmpty(&$arr,$trim = true,$unsetEmptyArr=false){ foreach ($arr as $key => $value) { if(is_array($value)) { _arrRemoveEmpty($arr[$key]); }else{ $value = trim($value); if ($value == '') { unset($arr[$key]); }elseif ($trim){ $arr[$key] = $value; } } } if(is_bool($unsetEmptyArr) && $unsetEmptyArr){ $arr = array_filter($arr); } return $arr; }
$entry = array(
0 => 'foo' ,
1 => false ,
2 => - 1 ,
3 => null ,
4 => '',
['aa'=>'',false,true,'dd'],
[false]
);
print_r(_arrRemoveEmpty($entry,1,true));
Array ( [0] => foo [2] => -1 [5] => Array ( [1] => 1 [2] => dd ) )
这里主要利用了php内置函数array_filter()的功能还有递归。
数组中字段替换。
我们替换数组的值会用php自带函数array_replace() ,手册解释如下
array_replace() 函数使用后面数组元素的值替换第一个 array
数组的值。如果一个键存在于第一个数组同时也存在于第二个数组,它的值将被第二个数组中的值替换。如果一个键存在于第二个数组,但是不存在于第一个数组,则会在第一个数组中创建这个元素。如果一个键仅存在于第一个数组,它将保持不变。如果传递了多个替换数组,它们将被按顺序依次处理,后面的数组将覆盖之前的值。
$arr1 = ['id' => 10, 'name' => 'jack', 'sex' => 'man']; $arr2 = ['id' => 12, 'name' => 'tom', 'sex' => 'female','height'=>'162cm']; $arr = array_replace($arr1,$arr2);
print_r($arr);
Array ( [id] => 12 [name] => tom [sex] => female [height] => 162cm )
结果中$arr1里没有键值'height'=>'162cm'也被添加进去了,如果开发中不想新增,只想替换有的。
下面这个函数可以实现该功能。
function _arrOverWrite($array, $cover_array){ $key_intersect_arr = array_intersect_key($cover_array, $array);//返回$cover_array出现在$array的键名的值 foreach ($key_intersect_arr as $key => $value) { $array[$key] = $value;//替换赋值 } if (func_num_args() > 2) { foreach (array_slice(func_get_args(), 2) as $cover_array) { foreach (array_intersect_key($cover_array, $array) as $key => $value) { $array[$key] = $value; } } } return $array; } $arr1 = ['id' => '111', 'name' => 'jack', 'sex' => 'man','hobby'=>'book']; $arr2 = ['id' => '222', 'name' => 'tom', 'sex' => 'female','height'=>'162cm']; $arr3 = ['id' => '333', 'name' => 'kate', 'sex' => 'female','height'=>'162cm']; $arr = _arrOverWrite($arr1,$arr2,$arr3); print_r($arr);
打印出
Array ( [id] => 333 [name] => kate [sex] => female [hobby] => book )
判断数组是否是关联数组
function _is_assoc(array $array){ $keys_arr = array_keys($array); return array_keys($keys_arr) !== $keys_arr; } $arr1 = ['one'=>'aa','two'=>'tt']; var_dump((_is_assoc(['one'=>'aa','two'=>'tt'])));
bool(true)
快速检查数组中是否存在某个值
这个函数手册里有,工作中直接用这个
function _fast_in_array($needle, array $haystack, $strict = false){ $c = count($haystack); if($strict !== true){ for($i = 0; $i < $c; $i++){ if($haystack[$i] == $needle){ return true; } } }else{ for($i = 0; $i < $c; $i++){ if($haystack[$i] === $needle){ return true; } } } return false; } var_dump(_fast_in_array('aa',['aa','bb','cc'])); //true
合并多个数组
/* * 作用 递归合并两个或多个数组。关联数组中的值用相同的键覆盖以前的值。索引数组中的值,被追加,但只有在结果中不存在时才追加。 * $array1 arr * $array2 arr * return merged_arr */ function _recursively_array_merge($array1, $array2){ if (_is_assoc($array2)) {//关联数组 foreach ($array2 as $key => $value) { if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])){ $array1[$key] = _recursively_array_merge($array1[$key], $value); }else{ $array1[$key] = $value; } } }else{//索引数组 foreach ($array2 as $value){ if (!in_array($value, $array1, true)){ $array1[] = $value; } } } if (func_num_args() > 2){ foreach (array_slice(func_get_args(), 2) as $array2){ if (_is_assoc($array2)){ foreach ($array2 as $key => $value){ if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])){ $array1[$key] = _recursively_array_merge($array1[$key], $value); }else{ $array1[$key] = $value; } } }else{ foreach ($array2 as $value){ if (!in_array($value, $array1, true)){ $array1[] = $value; } } } } } return $array1; }
$arr1 = ['one'=>'aaa','two'=>'bbb',['kk'=>'kk_val111']]; $arr2 = ['one'=>'aaa','two'=>'bbbttt',1,['kk'=>'kk_val',5,'abc'=>'ww']]; print_r(_recursively_array_merge($arr1,$arr2));
Array ( [one] => aaa [two] => bbbttt [0] => 1 [1] => Array ( [kk] => kk_val [0] => 5 [abc] => ww ) )
多维数组递归成一维数组
function _arr_flatten($array){ $isAssoc = _is_assoc($array); $flat_arr = []; foreach ($array as $key => $value) { if (is_array($value)) { $flat_arr = array_merge($flat_arr, _arr_flatten($value)); }else{ if ($isAssoc){ $flat_arr[$key] = $value; }else{ $flat_arr[] = $value; } } } return $flat_arr; }
$arr = ['foo'=>[ 'bar'=>'bar_value', 'bar_two'=>'bar_two_value', 'bar_keys'=>[ 'a'=>'aaa', 'b'=>'bbb', 'c'=>'ccc', ] ],1,[1,2],'top'=>[ 'top_bar1'=>'top_bar_value1', 'top_bar2'=>'top_bar_value2', ]]; print_r(_arr_flatten($arr));
Array (
[bar] => bar_value
[bar_two] => bar_two_value
[a] => aaa
[b] => bbb
[c] => ccc
[0] => 1
[1] => 1
[2] => 2
[top_bar1] => top_bar_value1
[top_bar2] => top_bar_value2
)
通过自定义分隔符设置路径获取数组中的值
比如有个多维数组
$arr = ['foo'=>[
'bar'=>'bar_value',
'bar_two'=>'bar_two_value',
'bar_keys'=>[
'a'=>'aaa',
'b'=>'bbb',
'c'=>'ccc',
]
],1,[1,2],'top'=>[
'top_bar1'=>'top_bar_value1',
'top_bar2'=>'top_bar_value2',
]];
我想通过foo.bar_keys 这样的方式获取数组 $arr 在键为foo里面键为bar_keys的值
/* * $array arr * $path 自定义路径 * $default 默认返回值 * $delimiter 分隔符 */ function _path($array, $path, $default = null, $delimiter = null){ if (!_is_array($array)) { return $default; } if (is_array($path)) { $keys = $path; }else { if (array_key_exists($path,$array)) { return $array[$path]; } if ($delimiter === null) { $delimiter = '.'; } $path = ltrim($path, "{$delimiter}"); // 删除右边的delimiters, 空格,通配符 $path = rtrim($path, "{$delimiter} *");//包含空格 $keys = explode($delimiter, $path); } do { $key = array_shift($keys);//将数组开头的单元移出数组 最终清空数组 if (ctype_digit($key)) {//ctype_digit()做纯数字检测 $key = (int) $key; } if (isset($array[$key])) { if ($keys) { if (_is_array($array[$key])) { $array = $array[$key];//给$array在赋值 }else { break; } } else { return $array[$key]; } } elseif ($key === '*') { $values = []; foreach ($array as $arr) { if ($value = _path($arr, implode('.', $keys))) { $values[] = $value; } } if ($values) { return $values; } else { break; } } else { break; } }while ($keys); return $default; } print_r(_path($arr,'foo.bar_keys')) ;
打印出
Array ( [a] => aaa [b] => bbb [c] => ccc )
也可以用*号,获取键top下所有的值
print_r(_path($arr,'top.*')) ;
结果是
Array ( [top_bar1] => top_bar_value1 [top_bar2] => top_bar_value2 )
添加多个键值对到一个数组前面
$arr = ['one'=>'one_value','two'=>'two_value']; array_unshift ( $arr , ['three_value'=>'three'] ); array_unshift ( $arr , ['four'] ); print_r ( $arr );
结果是
Array ( [0] => Array ( [0] => four ) [1] => Array ( [three_value] => three ) [one] => one_value [two] => two_value )
可是这不是我想要的结果
function _arr_prepend($array, $append_arr){ if(!empty($append_arr)){ while (list( $key , $val ) = each ( $append_arr )) { if(is_numeric($key)) { array_unshift($array, $val); }else { $array = [$key => $val] + $array; } } } return $array; } $arr = ['one'=>'one_value','two'=>'two_value']; print_r(_arr_prepend($arr,['four','three_value'=>'three']));
结果
Array ( [three_value] => three [0] => four [one] => one_value [two] => two_value )
更新中.....
上一篇: 盘点历史上有名的五个预言 桃李子有天下
下一篇: Rushmail:邮件推广小技巧