Возможно ли удалить весь массив на основе наличия одного значения без перестройки массива?

#php #arrays #object

#php #массивы #объект

Вопрос:

У меня есть два массива, первый ($ needles) содержит кучу объектов, второй ($ stack) содержит кучу ключей / значений, но где одно значение представляет собой массив объектов, похожих на первый массив.

Как я могу удалить все объекты в пределах значения target_p в $ stack, где c_id соответствует любому из объектов в $ needle?

Спасибо

 Array ($needles)
(
    [0] => stdClass Object
        (
            [c_id] => 305164
            [neg] => 
            [seconds] => 604800
            [f_min] => 10
        )

    [1] => stdClass Object
        (
            [c_id] => 305165
            [neg] => 
            [seconds] => 604800
            [fr_min] => 10
        )

    [2] => stdClass Object
        (
            [c_id] => 305166
            [neg] => 
            [seconds] => 604800
            [f_min] => 10
        )

)
*****************
Array ($stack)
(
    [req_all] => 
    [target_p] => Array
        (
            [0] => stdClass Object
                (
                    [c_id] => 305164
                    [pid] => 2323554
                    [neg] => 
                    [seconds] => 
                    [f_min] => 
                )

            [1] => stdClass Object
                (
                    [c_id] => 305165
                    [pid] => 1964608
                    [neg] => 
                    [seconds] => 
                    [f_min] => 
                )

            [2] => stdClass Object
                (
                    [c_id] => 305166
                    [neg] => 1
                    [seconds] => 604800
                    [f_min] => 
                )

            [3] => stdClass Object
                (
                    [c_id] => 305167
                    [neg] => 1
                    [seconds] => 604800
                    [f_min] => 
                )

            [4] => stdClass Object
                (
                    [c_id] => 314022
                    [pid] => 4950148
                    [neg] => 
                    [seconds] => 
                    [f_min] => 
                )

        )

    [logical_e] => 
)
  

Желаемый результат:

 Array ($stack)
(
    [req_all] => 
    [target_p] => Array
        (
            [0] => stdClass Object
                (
                    [c_id] => 305167
                    [neg] => 1
                    [seconds] => 604800
                    [f_min] => 
                )

            [1] => stdClass Object
                (
                    [c_id] => 314022
                    [pid] => 4950148
                    [neg] => 
                    [seconds] => 
                    [f_min] => 
                )

        )

    [logical_e] => 
)
  

Ответ №1:

Без перестройки массива? Не совсем. Но это все равно легко.

Перестройте массив needles с ключами, соответствующими c_id значениям:

 $o_needles = array();
foreach ($needles as $needle) {
    $o_needles[$needle->c_id] = $needle;
}
  

Затем удалите все узлы в стеке, которые имеют c_id значение, соответствующее ключу в измененном массиве needles:

 foreach ($stack['target_p'] as $key => $obj) {
    if (array_key_exists($obj->c_id, $o_needles)) {
        unset($stack['target_p'][$key]);
    }
}
  

Производительность / сложность составляет O (n m).

Если бы вы использовали функцию типа array_map , array_walk , array_filter или вложенную foreach , вам пришлось бы просматривать каждую из игл для каждого элемента в стеке, что было бы менее эффективно, особенно с большими наборами данных (O (n * m)).

Ответ №2:

С помощью unset() ?.

Я не думаю, что я четко понял, что именно вам нужно, и поэтому приведу 2 примера (Вы действительно должны предоставить желаемый результат, чтобы мы могли проверить, правильно ли мы вас поняли).

Удалить элемент массива из $stack[‘target_p’], если c_id такого элемента совпадает с идентификатором в массиве $needles:

 foreach ($stack['target_p'] as $k => $v)
{
    foreach ($needles as $needle)
    {
        if ($v->c_id == $needle->c_id) {
            unset($stack['target_p'][$k]);
        }
    }
}
  

Удалить все элементы массива из $stack[‘target_p’], если какой-либо c_id совпадает с тем же в массиве $ needles:

 foreach ($stack['target_p'] as $k => $v)
{
    foreach ($needles as $needle)
    {
        if ($v->c_id == $needle->c_id) {
            $stack['target_p'] = array(); // will delete elements but preserver target_p key
            // or
            unset($stack['target_p']); // will delete elements amp; target_p key

            break 2; // exit from both foreach loops
        }
    }
}
  

Комментарии:

1. @Dan: Спасибо за предоставление желаемых результатов. Мой пример # 1 выполнит эту работу так же хорошо, как и тот, который предоставляется netcoder , который оптимизирован для / работает быстрее с большими массивами (но может быть сложнее понять, как это работает для вас, поскольку вы задаете этот вопрос — но это лучше в долгосрочной перспективе :)).

2. Спасибо! Я всегда стараюсь понять любое решение, поэтому я только что закончил устраиваться с обоими ответами. Я буду использовать большие наборы данных, или, по крайней мере, я не планирую ограничивать размер, поэтому выбрал решение netcoder. Спасибо, что уделили время. 10.

Ответ №3:

Используйте array_filter() .