PHP 关联数组操作太麻烦,试试这几个 WPJAM Basic 内置的数组处理函数

2023-04-13 10:59:57 浏览数 (1)

PHP 有很多非常好用的数组处理函数,PHP 数组函数官方文档都有 80 多个,但是在使用过程,有一些数组的操作使用比较多,我就把这些函数整理成工具函数,然后整合到 WPJAM Basic 中,方便自己的二次开放时候使用,现在整理放出来,如果你和我一样基于 WPJAM Basic 进行二次开发,也可以使用:

wpjam_array_excerpt

PHP 从关联数组中移除指定的键值对,一般使用 unset 函数,比如:

代码语言:javascript复制
$array	= ['name' => 'Desk', 'description'=>'long description' 'price' => 100];

unset($array['price']);
unset($array['description']);

print_r($array);	// ['name' => 'Desk']

如果要移除多个键值对,就要调用多次的 unset 函数,所以就合并成一个函数 :

代码语言:javascript复制
function wpjam_array_except($array, $keys){
	if(is_string($keys)){
		$keys	= [$keys];
	}

	foreach($keys as $key){
		unset($array[$key]);
	}

	return $array;
}

这样就可以通过下面方式移除键值对了:

代码语言:javascript复制
$array = wpjam_array_except($array, ['price','description']);

如果仅仅移除一个键值对,还可以直接传递字符串:

代码语言:javascript复制
$array = wpjam_array_except($array, 'price'); 

wpjam_array_filter

我们使用 array_filter 对数组进行过滤的时候,是不会递归调用的,意思如果其中元素也是数组的时候,是不会进行同样的过滤的操作。

代码语言:javascript复制
$array	= ['a'=>'a', 'b'=>null, 'c'=>['c1'=>'c1', 'c2'=>null, 'c3'=>'c3']];

var_dump(array_filter($array, 'is_exists'));

输出结果为:

代码语言:javascript复制
array(2) {
  ["a"] => string(1) "a"
  ["c"] => array(3) {
    ["c1"] => string(2) "c1"
    ["c2"] => NULL
    ["c3"] => string(2) "c3"
  }
}

但是我们在一些数据处理的时候,比如后台字段提交的时候,我们希望过滤掉 null 的值,如果元素也是一个关联数组的时候,我们希望关联数组元素中的 null 的值也会过滤掉。所以我们就写了 wpjam_array_filter 这个函数,实现 array_filter 递归调用:

代码语言:javascript复制
function wpjam_array_filter($array, $callback, $mode=0){
	foreach($array as $key=>&$value){
		if(is_array($value)){
			$value	= wpjam_array_filter($value, $callback, $mode);
		}
	}

	return array_filter($array, $callback, $mode);
}

同样的数组:

代码语言:javascript复制
$array	= ['a'=>'a', 'b'=>null, 'c'=>['c1'=>'c1', 'c2'=>null, 'c3'=>'c3']];

var_dump(wpjam_array_filter($array, 'is_exists'));

输出结果为:

代码语言:javascript复制
array(2) {
  ["a"] => string(1) "a"
  ["c"] => array(2) {
    ["c1"] => string(2) "c1"
    ["c3"] => string(2) "c3"
  }
}

wpjam_array_first

PHP 的 array_filter() 函数让我们可以通过回调函数来过滤数组,但是返回的是过滤后的数组,但是很多时候,我们只是简单的要求返回过滤之后数组的第一个元素

代码语言:javascript复制
function wpjam_array_first($array, $callback=null){
	if(!is_array($array)){
		return null;
	}

	if($callback && is_callable($callback)){
		foreach($array as $key => $value){
			if(call_user_func($callback, $value, $key)){
				return $value;
			}
		}
	}else{
		return current($array);
	}
}

使用非常简单的:

代码语言:javascript复制
$array	= [100, 200, 300];
$value	= wpjam_array_first($array, function($value) {
	return $value >= 150;
});
// 200

wpjam_array_merge

如果我们要合并的数组是多维的关联数组,那么使用 array_merge_recursive() 函数进行合并的话,不会进行键名覆盖,而是将多个相同键名的值递归合并成一个数组。

代码语言:javascript复制
$ar1 = array("color" => array("red", "green"), "aa");
$ar2 = array("color" => array( "green", "blue"), "bb");
$result = array_merge_recursive($ar1, $ar2);

print_r($result);

输出结果:

代码语言:javascript复制
[
    'color' => [
        (int) 0 => 'red',
        (int) 1 => 'green',
        (int) 2 => 'green',
        (int) 3 => 'blue'
    ],
    (int) 0 => 'aa',
    (int) 1 => 'bb'
]

其实我们希望子数组里面的相同的值覆盖,据此我们写了一个函数,用来深度合并多维数组:

代码语言:javascript复制
function wpjam_array_merge($arr1, $arr2){
	foreach($arr2 as $key => $value){
		if((is_array($value) && !wp_is_numeric_array($value))
			&& (isset($arr1[$key]) && is_array($arr1[$key]) && !wp_is_numeric_array($arr1[$key]))
		){
			$arr1[$key]	= wpjam_array_merge($arr1[$key], $value);
		}else{
			$arr1[$key]	= $value;
		}
	}

	return $arr1;
}

相同的数组进行合并:

代码语言:javascript复制
$ar1 = array("color" => array("red", "green"), "aa");
$ar2 = array("color" => array( "green", "blue"), "bb");
$result = wpjam_array_merge($ar1, $ar2);

print_r($result);

得到的结果是:

代码语言:javascript复制
[
    'color' => [
        (int) 0 => 'green',
        (int) 1 => 'blue'
    ],
    (int) 0 => 'bb'
]

一般不推荐使用 wpjam_array_merge 对多维索引数组进行合并。

wpjam_array_pull

要从关联数组中移除并返回指定的键值,一般需要两步操作,先取出,然后 unset 数组中的键值对:

代码语言:javascript复制
$array	= ['name' => 'Desk', 'price' => 100];
$value	= $array['name'];
unset($array['name']);

如果每次都这么操作,有点烦人,所以就把这两个步骤合成一个函数,并且还可以设置数组中无此键对应的元素的时候的默认值。

代码语言:javascript复制
function wpjam_array_pull(&$array, $key, $default=null){
	if(isset($array[$key])){
		$value	= $array[$key];

		unset($array[$key]);
		
		return $value;
	}else{
		return $default;
	}
}

然后直接调用即可:

代码语言:javascript复制
$name	= wpjam_array_pull($array, 'name');

wpjam_array_push

PHP 关联数组可以通过三种方式插入新元素:

代码语言:javascript复制
$array[$insert_key] = $insert_value;			// 插在最后
$array	= array_merge($array, $insert_array);	// 合并到最后
$array	= $array $insert_array;					// 插在最前面

由此可见,关联数组插入元素是无法指定位置的,只能插在最前或者最后面,所以这个函数就是实现向关联数组插入元素时候指定的 Key 之前

代码语言:javascript复制
function wpjam_array_push(&$array, $data, $key=null){
	if(!is_array($array) || !is_array($data) || wp_is_numeric_array($data)){
		return;
	}

	if(is_null($key)){
		$offset	= false;
	}else{
		$offset	= array_search($key, array_keys($array), true);
	}

	if($offset !== false){
		$array	= array_merge(array_slice($array, 0, $offset), $data, array_slice($array, $offset));
	}else{
		$array	= array_merge($array, $data);
	}
}

比如下面在 $columns'author' 之前插入 ['page_title'=>'页面标题']

代码语言:javascript复制
wpjam_array_push($columns, ['page_title'=>'页面标题'], 'author');

0 人点赞