我有一个看起来像这样的数组:
array(
0 => array(
'key1' => 'a',
'key2' => 'b',
'key3' => 'c'
),
1 => array(
'key1' => 'c',
'key2' => 'b',
'key3' => 'a'
),
...
)
我需要一个函数来获取一个只包含(变量)键数的数组,即reduce_array(array('key1','key3'));应该回来:
array(
0 => array(
'key1' => 'a',
'key3' => 'c'
),
1 => array(
'key1' => 'c',
'key3' => 'a'
),
...
)
最简单的方法是什么?如果可能的话,没有任何额外的辅助函数,比如array_filter或array_map,因为我的同事已经抱怨我使用了太多函数。
源数组将始终具有给定的键,因此不需要检查是否存在。
如果值是唯一的,则奖励积分(键将始终彼此相关,这意味着如果key1具有值a,则其他键将始终具有值b)。
我当前的解决方案有效,但非常笨拙(即使这个名字太可怕但找不到更好的名字):
function get_unique_values_from_array_by_keys(array $array, array $keys)
{
$result = array();
$found = array();
if (count($keys) > 0)
{
foreach ($array as $item)
{
if (in_array($item[$keys[0]], $found)) continue;
array_push($found, $item[$keys[0]]);
$result_item = array();
foreach ($keys as $key)
{
$result_item[$key] = $item[$key];
}
array_push($result, $result_item);
}
}
return $result;
}
加成:
PHP版本是5.1.6。
答案 0 :(得分:6)
如果你的同事不喜欢array_filter或array_map,那就是他们缺乏教育和品味。虽然我不建议在工作中燃烧桥梁,但它们通常是解决问题的最佳方法。
function reduce_array($array, $keys) { $keys_map = array_fill_keys($keys, true); return array_map(function ($subarray) use ($keys) { return array_intersect_key($subarray, $keys_map); }, $array); }
(注意:我上面使用的匿名函数仅在PHP> = 5.3中可用,因此您可能无法使用它们)
如果必须在没有array_map和匿名函数的情况下执行此操作:
function reduce_array($array, $keys) { $ret = array(); $keys_map = array_fill_keys($keys, true); foreach ($array as $subarray) { array_push($ret, array_intersect_key($subarray, $keys_map)); } return $ret; }
简要解释一下:首先,我使用array_fill_keys
将整数索引数组中的键转换为字符串索引数组(我给它的值,true
,这里并不重要)。这使它成为array_intersect_key
的合适输入,可以实现您正在寻找的精确缩减。
答案 1 :(得分:1)
仅使用in_array()函数。可以减少字符数,但我们会让它可读:
function reduce_array($array, $keys) {
$res=array(); // Our result array
foreach($array as $v1){ // Loop thru original array
$t1=array(); // Our new inner array
foreach($v1 as $k2=>$v2){ // Loop thru original inner array
if(in_array($k2,$keys)) $t1[$k2]=$v2; //If inside inner array store
}
$res[]=$t1; //Add to result array
}
return($res);
}
我很想摆脱in_array()函数,但我真的必须做一些工作;)