我使用标准PHP编码进行了以下工作,涉及循环和事物。 但是,我确信我可以结合使用所有PHP数组函数来完成相同的算法:array_intersect *,array_fill *和co ...
我希望有人已经遇到了这种情况,并找到了一种快速的方法。
好,这是:
我有一个索引数组,我们称它为数据,它包含大量有关实体的信息,顺序显然并不重要,因为它毕竟是索引数组:
$data = [
'title' => 'loops and things',
'id' => '28fr2',
'link' => 'https://blah',
'itemid' => '28fr3',
'quantity' => 3,
//...
];
现在,我有一组其他数组,这些数组描述了我的数据数组的一个子集,例如:
$product = [
'id',
'title',
'link'
];
和
$inventory = [
'itemid',
'quantity',
];
我追求的是类似的东西
array_intersect_key_while_we_keep_the_order($data, $product);
会给
[
'id' => '28fr2',
'title' => 'loops and things',
'link' => 'https://blah'
]
和
array_intersect_key_while_we_keep_the_order($data, $inventory);
会给
[
'itemid' => '28fr2',
'quantity' => 3
]
array_intersect_key存在的问题是“顺序”来自源数组,而不是定义键列表的源。 使用foreaches显然很简单,但是我相信它可以更快地完成。我只是看不到。
答案 0 :(得分:2)
非常简单
$data = [
'title' => 'loops and things',
'id' => '28fr2',
'link' => 'https://blah',
'itemid' => '28fr3',
'quantity' => 3,
//...
];
$product = [
'id',
'title',
'link'
];
$res = array_merge(array_fill_keys($product, null),array_intersect_key($data, array_flip($product)));
print_r($res);
输出
Array
(
[id] => 28fr2
[title] => loops and things
[link] => https://blah
)
它是如何工作的,这里的主要技巧是数组填充键和数组合并。通过使用这些,我们可以创建一个“模板”数组。因为合并具有相同键的2个数组将按第一个数组的顺序合并。因此,我们可以将第一个数组设置为$product
的顺序,然后在合并到其中时,将“假”值替换为实际值,并保留顺序。
如果您愿意,也可以使用数组翻转(或数组填充键)的结果,但是它将是两行代码...:)
当然,我们必须使用数组翻转或数组填充键之类的东西来将$product
的值更改为可用于数组相交键的键。
我同时使用了数组填充键和数组翻转功能,在这种情况下它们可以互换。例如,这样会更有效:
$map = array_fill_keys($product, null);
$res = array_merge($map,array_intersect_key($data, $map));
print_r($res);
但是这需要2行...我应该提到数组填充键比数组翻转更可取。没关系,因为数组相交键会过滤掉地图中未包含的所有内容。但这“更好”,因为映射数组的值是相同的,而当使用翻页时,它们是数字键,在某些情况下(但不是在这种情况下)使用起来会有点困难。
几乎可以,您可以像这样使用它
function ordered_array_intersect_key(array $data, array $map){
return array_merge(($map = array_fill_keys($map, null)),array_intersect_key($data, $map));
}
我随意命名它,并在array_merge
中使用内联赋值,您也可以吃蛋糕也可以吃(重复使用array_fill_keys并有1行)。我刚想出一个函数时会想到的东西。
享受!
更新
感谢mosh442提出的想法。您还可以使用array_walk
来构建一个新的数组,如下所示:
$data = [
'title' => 'loops and things',
'id' => '28fr2',
'link' => 'https://blah',
'itemid' => '28fr3',
'quantity' => 3,
//...
];
$product = [
'id',
'title',
'link'
];
$new = [];
array_walk($product, function($v,$k,$data) use (&$new){$new[$v] = $data[$v];},$data);
print_r($new);
输出
Array
(
[id] => 28fr2
[title] => loops and things
[link] => https://blah
)
我喜欢这样的问题,非常有趣。...
答案 1 :(得分:0)
您也可以使用array_filter
array_filter(
$data,
function ($key) use ($inventory) {return in_array($key,$inventory);} ,
ARRAY_FILTER_USE_KEY
);
如注释中所述,在PHP 5.6.0中添加了ARRAY_FILTER_USE_KEY标志