I have an Array that looks like this:
我有一个这样的数组:
array(
0 => array(
'key1' => 'a',
'key2' => 'b',
'key3' => 'c'
),
1 => array(
'key1' => 'c',
'key2' => 'b',
'key3' => 'a'
),
...
)
I need a function to get an array containing just a (variable) number of keys, i.e. reduce_array(array('key1', 'key3')); should return:
我需要一个函数来获取一个数组,该数组只包含一个(变量)的键数,即reduce_array(数组,'key1', 'key3');应该返回:
array(
0 => array(
'key1' => 'a',
'key3' => 'c'
),
1 => array(
'key1' => 'c',
'key3' => 'a'
),
...
)
What is the easiest way to do this? If possible without any additional helper function like array_filter or array_map as my coworkers already complain about me using too many functions.
最简单的方法是什么?如果可能的话,不需要像array_filter或array_map这样的辅助函数,因为我的同事已经在抱怨我使用了太多的函数。
The source array will always have the given keys so it's not required to check for existance.
源数组将始终具有给定的键,因此不需要检查存在性。
Bonus points if the values are unique (the keys will always be related to each other, meaning that if key1 has value a then the other key(s) will always have value b).
如果值是唯一的(键始终是相互关联的,这意味着如果key1具有值a,那么其他键将始终具有值b)。
My current solution which works but is quite clumsy (even the name is horrible but can't find a better one):
我目前的解决方案是可行的,但是很笨拙(即使名字很可怕,但是找不到更好的):
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;
}
Addition:
PHP Version is 5.1.6.
另外:PHP版本是5.1.6。
2 个解决方案
#1
6
If your coworkers don't like array_filter or array_map, that is their lack of education and taste. While I don't advise burning bridges at work, they frequently are the best way to solve a problem.
如果你的同事不喜欢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); }
(Note: the anonymous functions I use above are only available in PHP >= 5.3, so you probably can't use them)
(注意:上面使用的匿名函数只在PHP >= 5.3中可用,所以您可能无法使用它们)
If you must do it without array_map and anonymous functions:
如果您必须在没有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; }
To briefly explain: first, I use array_fill_keys
to turn keys from an integer-indexed array to a string-indexed array (the value I give it, true
, doesn't really matter here). This makes it suitable input for array_intersect_key
, which will do the exact reduction you're looking for.
简单解释一下:首先,我使用array_fill_keys将键从一个整数索引数组转换为一个字符串索引数组(我给出的值是true,在这里并不重要)。这使它适合于array_intersect_key的输入,它将执行您要查找的精确的缩减。
#2
1
Only using in_array() function. Character count can be reduced but we'll leave it readable:
只使用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);
}
I'm itching to get rid of the in_array() function as well but I really must do some work ;)
我也很想去掉in_array()函数,但是我必须做一些工作;)
#1
6
If your coworkers don't like array_filter or array_map, that is their lack of education and taste. While I don't advise burning bridges at work, they frequently are the best way to solve a problem.
如果你的同事不喜欢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); }
(Note: the anonymous functions I use above are only available in PHP >= 5.3, so you probably can't use them)
(注意:上面使用的匿名函数只在PHP >= 5.3中可用,所以您可能无法使用它们)
If you must do it without array_map and anonymous functions:
如果您必须在没有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; }
To briefly explain: first, I use array_fill_keys
to turn keys from an integer-indexed array to a string-indexed array (the value I give it, true
, doesn't really matter here). This makes it suitable input for array_intersect_key
, which will do the exact reduction you're looking for.
简单解释一下:首先,我使用array_fill_keys将键从一个整数索引数组转换为一个字符串索引数组(我给出的值是true,在这里并不重要)。这使它适合于array_intersect_key的输入,它将执行您要查找的精确的缩减。
#2
1
Only using in_array() function. Character count can be reduced but we'll leave it readable:
只使用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);
}
I'm itching to get rid of the in_array() function as well but I really must do some work ;)
我也很想去掉in_array()函数,但是我必须做一些工作;)