如何只保留数组中的特定数组键/值?

时间:2014-04-18 16:44:35

标签: php multidimensional-array

我有一个多维数组,我正在搜索特定值。 如果找到这些值,我需要使用这些值提取索引(创建新数组)并删除所有其他值。

array_intersect在php 5.3上运行良好,现在在5.4它抱怨注意:数组到字符串转换。

我发现array_intersect在5.4上有多维数组的问题。 https://bugs.php.net/bug.php?id=60198

这是我正在搜索的$ options数组

Array (

    [index1] => html
    [index2] => html
    [index3] => slide
    [index4] => tab
    [index5] => Array
        (
            [0] => 123
        )

)

适用于php 5.3.x的代码

$lookfor   = array('slide', 'tab');
$found     = array_intersect($options, $lookfor);


print_r($found);


Array
(
    [index3] => slide
    [index4] => tab
)

但在5.4.x中,这会产生上述错误。

请在没有循环的情况下执行此操作的另一种方法是什么。 并且没有压制错误。

谢谢!

3 个答案:

答案 0 :(得分:4)

array_intersect()不是递归的。该函数假定数组只有一个深度,并期望所有数组元素都是标量。当它找到一个非标量值,即一个子数组时,它会抛出一个Notice。

documentation for array_intersect()中含糊其词:

  

注意:当且仅当以下情况时,两个元素被认为是相等的:(字符串)$ elem1 ===(字符串)$ elem2。用文字表示:当字符串表示相同时。

我能想到的一个解决方案是使用array_filter()

$lookfor = array('html', 'slide');
$found   = array_filter($options, function($item) use ($lookfor) {
    return in_array($item, $lookfor);
});

注意:这仍然会执行循环,并不比简单的foreach好。实际上,如果数组很大,它可能比foreach慢。我不知道为什么你要试图避免循环 - 我个人认为如果你只是使用一个循环它会更清洁。

Demo

我能想到的另一个解决方案是在使用array_intersect()之前删除子数组:

<?php

$options = array(
    'index1' => 'html',
    'index2' => 'html',
    'index3' => 'slide',
    'index4' => 'tab',
    'index5' => array(123),
);

$lookfor = array('html', 'slide');
$scalars = array_filter($options,function ($item) { return !is_array($item); });
$found = array_intersect ($scalars, $lookfor);

print_r($found);

Demo

答案 1 :(得分:3)

你可以使用array_filter()

$arr = array(
  'index1' => 'html',
  'index2' => 'html',
  'index3' => 'slide',
  'index4' => 'tab',
  'index5' => array(0 => 123),
);

$with = array('html', 'slide');
$res = array_filter($arr, function($val) use ($with) {
    return in_array($val, $with);
});

这将重新转换index1,index2和index3。

编辑:只需阅读您的评论,您的数组将包含大量条目。 array_filter当然会以条件循环并创建一个新数组。

答案 2 :(得分:2)

$array = [
    'a' => 4,
    's' => 5,
    'd' => 6,
];
$onlyKeys = ['s','d'];

$filteredArray = array_filter($array, function($v) use ($onlyKeys) {
    return in_array($v, $onlyKeys);
}, ARRAY_FILTER_USE_KEY);

prinr_r($filteredArray); //  ['s' => 5, 'd' => 6]

要按值过滤,请从参数列表中删除 ARRAY_FILTER_USE_KEY。