#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()
.