Я работаю с 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++;
}
Кажется, что он оценивает только первое значение, а затем выходит. Любая помощь?
Я бы предпочел использовать с этим foreach, чтобы у меня не было необходимости использовать count.
@Ghost, это было то, что я пробовал, но я понял, что помещаю инкремент внутри условия if, а не снаружи. Спасибо






Вам нужно будет использовать условие внутри цикла. Попробуйте следующий код:
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, а не снаружи, поэтому оно будет выполнено один раз, а затем преждевременно завершится
Самый простой и читаемый способ с использованием 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 для построения выходной строки.
Выход:
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;
}
);
выньте (удалите) условие
isLoanOfficerвнутри цикла while, используйте это условие внутри блока while с if, чтобы у вас был полный запуск с каждым элементом, в настоящее время ваш цикл while завершится преждевременно