#php #arrays #loops #filter
#php #массивы #циклы #Фильтр
Вопрос:
У меня есть этот массив :
(
[id] => block_5df755210d30a
[name] => acf/floorplans
[data] => Array
(
[floorplans_0_valid_for_export] => 0
[floorplans_0_title] => title 1
[floorplans_0_house_area] => 40m²
[floorplans_0_bedrooms] => 1
[floorplans_1_valid_for_export] => 1
[floorplans_1_title] => title xx
[floorplans_1_house_area] => 90m²
[floorplans_1_bedrooms] => 2
[floorplans_2_valid_for_export] => 1
[floorplans_2_title] => title 2
[floorplans_2_house_area] => 50m²
[floorplans_2_bedrooms] => 1
[floorplans] => 3
)
)
Как мы можем видеть в данных, у нас есть fields ( floorplans_X_valid_for_export
) .
Что я хочу сделать, так это получить данные только тогда, когда это поле равно 1
.
Итак, из приведенного примера я хочу сохранить только эти поля:
[floorplans_1_valid_for_export] => 1
[floorplans_1_title] => title xx
[floorplans_1_house_area] => 90m²
[floorplans_1_bedrooms] => 2
[floorplans_2_valid_for_export] => 1
[floorplans_2_title] => title 2
[floorplans_2_house_area] => 50m²
[floorplans_2_bedrooms] => 1
Комментарии:
1. в
floorplans_X_valid_for_export
X всегда уникально, например, его нельзя повторить?2. Когда вы задаете вопрос, пожалуйста, не просто «сбрасывайте свои требования». Если вы программист, мы ожидаем увидеть ваш лучший сбой. При этом вы доказываете, что не используете SO как бесплатную службу кодирования, и добровольцам может быть проще исправить небольшую часть вашего скрипта вместо создания совершенно нового решения. Моя философия SO не позволяет мне поднимать вопрос без попытки кодирования.
Ответ №1:
Это странная схема, но это можно сделать, выполнив итерацию по массиву и выполнив поиск ключей, где «valid_for_export» равно 1, а затем используя другой массив «заглушек» полей, чтобы получить связанные элементы по уникальному идентификатору X в floorplans_X_valid_for_export
$array = [
'floorplans_0_valid_for_export' => 0,
'floorplans_0_title' => 'title 1',
'floorplans_0_house_area' => '40m²',
'floorplans_0_bedrooms' => 1,
'floorplans_1_valid_for_export' => 1,
'floorplans_1_title' => 'title xx',
'floorplans_1_house_area' => '90m²',
'floorplans_1_bedrooms' => '2',
'floorplans_2_valid_for_export' => 1,
'floorplans_2_title' => 'title 2',
'floorplans_2_house_area' => '50m²',
'floorplans_2_bedrooms' => 1,
'floorplans' => 3
];
$stubs = [
'floorplans_%s_valid_for_export',
'floorplans_%s_title',
'floorplans_%s_house_area',
'floorplans_%s_bedrooms'
];
$newArr = [];
foreach ($array as $key => $value) {
if (strpos($key, 'valid_for_export') amp;amp; $array[$key] == 1) {
$intVal = filter_var($key, FILTER_SANITIZE_NUMBER_INT);
foreach ($stubs as $stub) {
$search = sprintf($stub, $intVal);
if (isset($array[$search])) {
$newArr[$search] = $array[$search];
} else {
// key can't be found, generate one with null
$newArr[$search] = null;
}
}
}
}
echo '<pre>';
print_r($newArr);
Работает: http://sandbox.onlinephpfunctions.com/code/23a225e3cefa2dc9cc97f53f1cbae0ea291672c0
Комментарии:
1. Это решение — чистая поэзия. Единственное улучшение, которое я мог бы предложить, — это некоторые комментарии — даже опытному программисту придется все обдумать. Мне особенно нравится
$stub
sprintf
комбинация / .2. Есть более чистый способ сделать это.
Ответ №2:
Используйте родительский цикл, чтобы проверить, что valid_for_export
значение, зависящее от числа, не является пустым, поскольку оно равно либо 0, либо ненулевому.
Если это так, то просто вставьте все связанные элементы в результирующий массив.
Некоторые причины, по которым этот ответ превосходит ответ @Alex::
- Родительский цикл Алекса выполняет 13 итераций (и
strpos()
столько же вызовов); мой делает только 3 (и только 3 вызоваempty()
). $array[$key]
проще записывается как$value
.- Очистка
$key
для извлечения индекса / счетчика требует больше затрат, чем необходимо, как показано в моем ответе.
Код (демонстрационный)
$array = [
'floorplans_0_valid_for_export' => 0,
'floorplans_0_title' => 'title 1',
'floorplans_0_house_area' => '40m²',
'floorplans_0_bedrooms' => 1,
'floorplans_1_valid_for_export' => 1,
'floorplans_1_title' => 'title xx',
'floorplans_1_house_area' => '90m²',
'floorplans_1_bedrooms' => '2',
'floorplans_2_valid_for_export' => 1,
'floorplans_2_title' => 'title 2',
'floorplans_2_house_area' => '50m²',
'floorplans_2_bedrooms' => 1,
'floorplans' => 3
];
$labels = ['valid_for_export', 'title', 'house_area', 'bedrooms'];
$result = [];
for ($i = 0; $i < $array['floorplans']; $i) {
if (!empty($array['floorplans_' . $i . '_valid_for_export'])) {
foreach ($labels as $label) {
$key = sprintf('floorplans_%s_%s', $i, $label);
$result[$key] = $array[$key];
}
}
}
var_export($result);
Вывод:
array (
'floorplans_1_valid_for_export' => 1,
'floorplans_1_title' => 'title xx',
'floorplans_1_house_area' => '90m²',
'floorplans_1_bedrooms' => '2',
'floorplans_2_valid_for_export' => 1,
'floorplans_2_title' => 'title 2',
'floorplans_2_house_area' => '50m²',
'floorplans_2_bedrooms' => 1,
)
Комментарии:
1. Я буквально ответил через мгновение после того, как был принят предыдущий ответ. Я бы хотел, чтобы люди были более терпеливыми (или были готовы сдвинуть галочку), чтобы исследователям было легче найти лучший ответ.
2. ваш ответ более чистый, однако я бы предложил дословно проверить, равно ли значение 1, и сделать что-то вроде
$result[$key] = isset($array[$key]) ? $array[$key] : null;
, чтобы избежать потенциальных ошибок. похоже, что эта схема БД неправильно отформатирована, поэтому я бы полностью ожидал проблем с данными OP, которые мы не видим3. Я не вижу никаких доказательств в вопросе, что эти проблемы возникнут. Я согласен, что структура входящих данных не идеальна.
4. Понятно, но ошибки «неопределенный ключ массива» всегда печальны, когда их можно легко избежать.
5. Это «изобретенная» проблема. Объединение нулей было бы моим методом выбора, если бы угроза была реальной.
Ответ №3:
С этими сконструированными данными это может быть сложно (хотя и не невозможно), поэтому я бы предложил изменить его на многомерные массивы, чтобы у вас было что-то вроде:
[floorplans][0][valid_for_export] => 0
[floorplans][0][title] => title 1
[floorplans][0][house_area] => 40m²
[floorplans][0][bedrooms] => 1
[floorplans][1][valid_for_export] => 1
[floorplans][1][title] => title xx
[floorplans][1][house_area] => 90m²
Грубое решение
Это не лучший подход, но он должен работать, если вам не нужно ничего необычного, и вы знаете, что структура данных не изменится в будущем
$keys = [];
$for($i=0;$i<$array['floorplans']; $i) {
if(isset($array['floorplans_'.$i.'_valid_for_export']) amp;amp; $array['floorplans_'.$i.'_valid_for_export']===1) {
$keys[] = $i;
}
}
print_r($keys);
Комментарии:
1. Проблема в том, что я не могу изменить его структуру.
2. @AmjadKhalil я добавил грубое решение, оно не очень красивое, но должно выполнять свою работу
3. Уместно рекомендовать переструктурировать входящие данные — но это должен быть комментарий под вопросом. Второй фрагмент не обеспечивает желаемый результат. Это не очень хороший ответ.