Php 使用一个键数组过滤另一个数组,保留;订单“;

Php 使用一个键数组过滤另一个数组,保留;订单“;,php,arrays,Php,Arrays,我已经使用标准的PHP编码完成了以下内容,包括循环和其他内容。 尽管如此,我相信我可以使用所有PHP数组函数的组合来实现相同的算法:array_intersect*、array_fill*和co 我希望有人已经遇到了这一点,并找到了一种方法,一种快速的方法 好的,给你: 我有一个索引数组,我们称之为数据,它包含关于实体的大量信息,顺序显然不重要,因为它毕竟是一个索引数组: $data = [ 'title' => 'loops and things', 'id' =>

我已经使用标准的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'
];

我所追求的是:

array_intersect_key_while_we_keep_the_order($data, $product);
会给

[
    'id' => '28fr2',
    'title' => 'loops and things',
    'link' => 'https://blah'
]
[
    'itemid' => '28fr2',
    'quantity' => 3
]

会给

[
    'id' => '28fr2',
    'title' => 'loops and things',
    'link' => 'https://blah'
]
[
    'itemid' => '28fr2',
    'quantity' => 3
]
我对array_intersect_key的问题是,“顺序”来自源数组,而不是定义键列表的数组。 这显然是直截了当的使用前肢,但我相信它可以做得更快。我就是看不见。

很简单

$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
)
Array
(
    [id] => 28fr2
    [title] => loops and things
    [link] => https://blah
)

如何工作,这里的主要技巧是数组填充键和数组合并。通过使用这些,我们可以创建一个“模板”数组。因为合并具有相同键的两个数组会按照第一个数组的顺序合并。因此,我们可以将第一个数组设置为
$product
的顺序,然后当我们合并到该数组中时,“伪”值将替换为真实值,并保留顺序

如果您愿意,您也可以使用数组翻转(或数组填充键)的结果,但这将是两行代码…:)

当然,我们必须使用数组翻转或数组填充键之类的东西来将
$product
的值更改为可用于数组相交键的键

我同时使用了数组填充键和数组翻转键来增加多样性,在这种情况下,它们是可以互换的。例如,这会更有效一些:

$map = array_fill_keys($product, null);
$res = array_merge($map,array_intersect_key($data, $map));
print_r($res);

但这需要两行。。。我应该提到数组填充键比数组翻转键更可取。这其实并不重要,因为数组的intersect键会过滤掉地图中没有的任何内容。但它“一般”更好,因为贴图数组的值是相同的,而使用flip时,它们是数字键,在某些情况下(但在本例中不是这样)可能会更难使用

我差一点就明白了,你可以这样操作它

function ordered_array_intersect_key(array $data, array $map){
    return array_merge(($map = array_fill_keys($map, null)),array_intersect_key($data, $map));
}
我冒昧地给它起了个合理的名字,通过在
array\u merge
中使用赋值内联,你可以吃蛋糕,也可以吃蛋糕(重用array\u fill\u键,并有一行)。当我用它做函数的时候,我碰巧想到了一些事情

享受吧

更新

感谢mosh442的创意。您还可以使用
array\u 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
)
Array
(
    [id] => 28fr2
    [title] => loops and things
    [link] => https://blah
)

我喜欢这样的问题,非常有趣……

非常简单

$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
)
Array
(
    [id] => 28fr2
    [title] => loops and things
    [link] => https://blah
)

如何工作,这里的主要技巧是数组填充键和数组合并。通过使用这些,我们可以创建一个“模板”数组。因为合并具有相同键的两个数组会按照第一个数组的顺序合并。因此,我们可以将第一个数组设置为
$product
的顺序,然后当我们合并到该数组中时,“伪”值将替换为真实值,并保留顺序

如果您愿意,您也可以使用数组翻转(或数组填充键)的结果,但这将是两行代码…:)

当然,我们必须使用数组翻转或数组填充键之类的东西来将
$product
的值更改为可用于数组相交键的键

我同时使用了数组填充键和数组翻转键来增加多样性,在这种情况下,它们是可以互换的。例如,这会更有效一些:

$map = array_fill_keys($product, null);
$res = array_merge($map,array_intersect_key($data, $map));
print_r($res);

但这需要两行。。。我应该提到数组填充键比数组翻转键更可取。这其实并不重要,因为数组的intersect键会过滤掉地图中没有的任何内容。但它“一般”更好,因为贴图数组的值是相同的,而使用flip时,它们是数字键,在某些情况下(但在本例中不是这样)可能会更难使用

我差一点就明白了,你可以这样操作它

function ordered_array_intersect_key(array $data, array $map){
    return array_merge(($map = array_fill_keys($map, null)),array_intersect_key($data, $map));
}
我冒昧地给它起了个合理的名字,通过在
array\u merge
中使用赋值内联,你可以吃蛋糕,也可以吃蛋糕(重用array\u fill\u键,并有一行)。当我用它做函数的时候,我碰巧想到了一些事情

享受吧

更新

感谢mosh442的创意。您还可以使用
array\u 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
)
Array
(
    [id] => 28fr2
    [title] => loops and things
    [link] => https://blah
)


我喜欢这样的问题,非常有趣……

你也可以使用数组过滤器

array_filter(
            $data,
            function ($key) use ($inventory) {return in_array($key,$inventory);} ,
            ARRAY_FILTER_USE_KEY
            );

如注释中所述,在PHP5.6.0中添加了ARRAY\u FILTER\u USE\u KEY标志,您也可以使用ARRAY\u FILTER

array_filter(
            $data,
            function ($key) use ($inventory) {return in_array($key,$inventory);} ,
            ARRAY_FILTER_USE_KEY
            );

如注释中所述,在PHP5.6.0中添加了ARRAY_FILTER_USE_KEY标志

几乎是一样的,但是使用
ARRAY_replace()
Yea在这种情况下,ARRAY replace和ARRAY merge是相同的。它们之间唯一的真正区别是使用非关联数组时。数组合并将添加到数组中,当它们是数字时,将替换为wont。艺术凤凰,你让我大吃一惊。回答质量:5星,陈述:5星。你在我的蛋糕上加了樱桃。现在我就要吃它了,重用array_fill_key版本,用cream我喜欢PHP我能说什么,我也喜欢解决问题。对于开发人员来说,这是一项很好的技能。您还编写了一个很好的问题,其中包含可用的示例数据和来自该数据的预期结果。谢谢得出了几乎相同的结果,但是使用
array\u replace()
Yea在本例中,array replace和array merge是相同的。它们之间唯一的真正区别是使用非关联数组时。数组合并将添加到数组中,当它们