Сопоставление ключа и значения массива и отображение только тех, которые входят в сопоставленный результат

Я работаю с API, который предоставляет набор результатов в JSON, я преобразовываю эти данные в массив PHP, чтобы работать с ним в моем интерфейсе. Проблема, с которой я столкнулся сейчас, заключается в попытке отфильтровать данные на основе определенного ключа, имеющего определенное значение.

Вот возвращенный набор результатов:

[  
   {  
      "id":5,
      "firstname":"Joel ",
      "lastname":"Abase",
      "displayName":"Abase, Joel ",
      "officeId":3,
      "officeName":"Birmingham",
      "isLoanOfficer":true,
      "isActive":true
   },
   {  
      "id":1,
      "firstname":"Precious ",
      "lastname":"Love",
      "displayName":"Love, Precious ",
      "officeId":4,
      "officeName":"Manchester",
      "isLoanOfficer":true,
      "isActive":true
   },
   {  
      "id":2,
      "firstname":"Bernard ",
      "lastname":"Aikins",
      "displayName":"Aikins, Bernice ",
      "officeId":2,
      "officeName":"Manchester",
      "isLoanOfficer":false,
      "isActive":true
   },
   {  
      "id":8,
      "firstname":"Kwame",
      "lastname":"Joseph",
      "displayName":"Joseph, Kwame",
      "officeId":2,
      "officeName":"Manchester",
      "isLoanOfficer":true,
      "isActive":true,
      "joiningDate":[  
         2018,
         5,
         1
      ]
   },
   {  
      "id":4,
      "firstname":"Janine ",
      "lastname":"Hayden",
      "displayName":"Hayden, Janine ",
      "officeId":1,
      "officeName":"Head Office",
      "isLoanOfficer":false,
      "isActive":true
   },
   {  
      "id":6,
      "firstname":"Esther",
      "lastname":"Monroe",
      "displayName":"Monroe, Esther",
      "officeId":2,
      "officeName":"London",
      "isLoanOfficer":true,
      "isActive":true,
      "joiningDate":[  
         2017,
         11,
         1
      ]
   }
]

Я хотел бы отфильтровать результаты в цикле, в котором isLoanOfficer равно true, по сути, показывая только тех, кто является кредитным специалистом.

Вот что я пробовал до сих пор:

<div class = "col-sm-5">
<label class = "control-label" for = "staffId">Loan Officer<span style = "color:red;">*</span></label>
<?php 
$s = 0;
$temp_staff = json_decode($staff_json, true);
$count_staff = count($temp_staff);
    echo '<select class = "form-control" type = "text" name = "staffId" required>';
                echo "<option value = ". ">" . " </option>";
                    while($s < $count_staff && $temp_staff[$s]['isLoanOfficer'] == true){   

                        echo "<option value = " . $temp_staff[$s]['id'] . ">" . $temp_staff[$s]['displayName'] . " </option>";
                    $s++;


                } 
    echo '</select>'; 
?>
<br>
</div>

Я также попытался добавить этот код внутри цикла while:

if ($temp_staff[$s]['isLoanOfficer'] == true) {  
echo "<option value = " . $temp_staff[$s]['id'] . ">" . $temp_staff[$s]['displayName'] . " </option>";
                $s++;
}

Кажется, что он оценивает только первое значение, а затем выходит. Любая помощь?

выньте (удалите) условие isLoanOfficer внутри цикла while, используйте это условие внутри блока while с if, чтобы у вас был полный запуск с каждым элементом, в настоящее время ваш цикл while завершится преждевременно

Kevin 21.05.2018 11:31

Я бы предпочел использовать с этим foreach, чтобы у меня не было необходимости использовать count.

Kevin 21.05.2018 11:32

@Ghost, это было то, что я пробовал, но я понял, что помещаю инкремент внутри условия if, а не снаружи. Спасибо

Enoch 21.05.2018 11:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
3
46
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вам нужно будет использовать условие внутри цикла. Попробуйте следующий код:

while($s < $count_staff){
    if ($temp_staff[$s]['isLoanOfficer'] == true) {
        echo "<option value = " . $temp_staff[$s]['id'] . ">" . $temp_staff[$s]['displayName'] . " </option>";
    }
    $s++;
}

Из-за этого условия ваш $ s ++ не выполняется должным образом.

Надеюсь это поможет.

Ваш ответ правильный, моя проблема заключалась в том, что я поместил приращение $ s ++ внутри оператора if, а не снаружи, поэтому оно будет выполнено один раз, а затем преждевременно завершится

Enoch 21.05.2018 11:36

Самый простой и читаемый способ с использованием foreach:

$temp_staff = json_decode($staff_json, true);
foreach($temp_staff as $member) {
    if ($member['isLoanOfficer']) {
        echo '<option value = "' . $member['id'] . '">' . $member['displayName'] . '</option>';
    }
}

Вам не нужно зацикливаться.

Вы можете использовать array_intersect, array_intersect_key и array_column, чтобы найти истинные значения.

Сначала отфильтруйте столбец ссудоофицера и используйте array_intersect, чтобы получить только истинные значения. Теперь у нас есть массив с истинными значениями и соответствующий ему ключ. Используйте array_intersect_key, чтобы сопоставить его с исходным массивом, и возвращением будет ваш фильтрованный массив.

$arr = json_decode($str, true);
$loan = array_intersect(array_column($arr, "isLoanOfficer"), [true]);
var_dump(array_intersect_key($arr, $loan));

Отсюда не простой foreach, выводящий каждое значение, или использование implode для построения выходной строки.

https://3v4l.org/eh4uD

Выход:

array(4) {
  [0]=>
  array(8) {
    ["id"]=>
    int(5)
    ["firstname"]=>
    string(5) "Joel "
    ["lastname"]=>
    string(5) "Abase"
    ["displayName"]=>
    string(12) "Abase, Joel "
    ["officeId"]=>
    int(3)
    ["officeName"]=>
    string(10) "Birmingham"
    ["isLoanOfficer"]=>
    bool(true)
    ["isActive"]=>
    bool(true)
  }
  [1]=>
  array(8) {
    ["id"]=>
    int(1)
    ["firstname"]=>
    string(9) "Precious "
    ["lastname"]=>
    string(4) "Love"
    ["displayName"]=>
    string(15) "Love, Precious "
    ["officeId"]=>
    int(4)
    ["officeName"]=>
    string(10) "Manchester"
    ["isLoanOfficer"]=>
    bool(true)
    ["isActive"]=>
    bool(true)
  }
  [3]=>
  array(9) {
    ["id"]=>
    int(8)
    ["firstname"]=>
    string(5) "Kwame"
    ["lastname"]=>
    string(6) "Joseph"
    ["displayName"]=>
    string(13) "Joseph, Kwame"
    ["officeId"]=>
    int(2)
    ["officeName"]=>
    string(10) "Manchester"
    ["isLoanOfficer"]=>
    bool(true)
    ["isActive"]=>
    bool(true)
    ["joiningDate"]=>
    array(3) {
      [0]=>
      int(2018)
      [1]=>
      int(5)
      [2]=>
      int(1)
    }
  }
  [5]=>
  array(9) {
    ["id"]=>
    int(6)
    ["firstname"]=>
    string(6) "Esther"
    ["lastname"]=>
    string(6) "Monroe"
    ["displayName"]=>
    string(14) "Monroe, Esther"
    ["officeId"]=>
    int(2)
    ["officeName"]=>
    string(6) "London"
    ["isLoanOfficer"]=>
    bool(true)
    ["isActive"]=>
    bool(true)
    ["joiningDate"]=>
    array(3) {
      [0]=>
      int(2017)
      [1]=>
      int(11)
      [2]=>
      int(1)
    }
  }
}

Если вы хотите сохранить массивы, в которых есть только "isLoanOfficer":true, вы можете использовать array_filter:

$temp_staff = array_filter($temp_staff, function($x){
    return $x["isLoanOfficer"] === true;
}
);

Демо

Другие вопросы по теме