How to keep only specific array keys/values in array?

Refresh

November 2018

Views

9.8k time

4

I have a multidimensional array that I am searching trough for specific values. If those values are found I need to extract the indexes with those values ( make new array ) and remove all others.

array_intersect worked fine on php 5.3 , now on 5.4 it complains Notice: Array to string conversion.

I found that array_intersect has an issue with multidimensional array on 5.4. https://bugs.php.net/bug.php?id=60198

This is $options array I am searching trough

Array (

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

)

code that works on php 5.3.x

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


print_r($found);


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

but in 5.4.x this trows the error mentioned above.

What would be another way to do this without a loop please. and without suppressing the error.

Thank you!

2 answers

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);
});

это rerturn INDEX1, index2 и index3.

Редактирование: только что прочитал ваш комментарий , что ваш массив будет содержать множество записей. array_filterбудет петлевой курс с условием над ними и создать новый массив.

4

array_intersect()не является рекурсивным. Функция принимает массив глубока только один уровень и ожидает, что все элементы массива, чтобы быть скаляры. Когда он находит, не скалярное значение, т.е. суб-массив, он бросает уведомление.

Это смутно упоминается в документации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если массив велик. Я понятия не имею , почему вы пытаетесь избежать петли - я лично думаю , что это будет более чище , если вы просто использовать цикл.

демонстрация

Другое решение , которое я мог думать о том , чтобы удалить подмассивы перед использованием 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);

демонстрация