#php #arrays
#php #массивы
Вопрос:
Вот кое-что простое, на что кто-нибудь может ответить за меня. Я пробовал искать, но я не знаю, что я ищу на самом деле.
У меня есть массив из строки JSON в PHP с указанием актеров и членов съемочной группы для фильма.
Здесь я выбираю только людей с именем задания ‘Actor’
foreach ($movies[0]->cast as $cast) {
if ($cast->job == 'Actor') {
echo '<p><a href="people.php?id=' . $cast->id . '">' . $cast->name . ' - ' . $cast->character . '</a></p>';
}
}
Проблема в том, что я хотел бы иметь возможность ограничить количество людей с именем задания ‘Actor’, которых выводят. Скажем, первые 3.
Итак, как мне выбрать только первых 3 из этих пользователей из этого массива?
Комментарии:
1. другой вариант из приведенных ниже — добавить счетчик в цикл
Ответ №1:
ХОРОШО — это немного перебор для решения этой проблемы, но, возможно, это служит некоторым образовательным целям. PHP поставляется с набором итераторов, которые могут использоваться для абстрактной итерации по заданному набору элементов.
class ActorIterator extends FilterIterator {
public function accept() {
return $this->current()->job == 'Actor';
}
}
$maxCount = 3;
$actors = new LimitIterator(
new ActorIterator(
new ArrayIterator($movies[0]->cast)
),
0,
$maxCount
);
foreach ($actors as $actor) {
echo /*... */;
}
Расширяя абстрактный класс FilterIterator
, мы можем определить фильтр, который возвращает только действующих лиц из заданного списка. LimitIterator
позволяет ограничить итерацию заданным набором и ArrayIterator
является простым помощником для обеспечения совместимости собственных массивов с Iterator
интерфейсом. Итераторы позволяют разработчику создавать цепочки, которые определяют процесс итерации, что делает их чрезвычайно гибкими и мощными.
Как я уже говорил во введении: данная проблема может быть легко решена без этого итератора, но он предоставляет разработчику некоторые расширенные возможности и позволяет повторно использовать код. Вы могли бы, например, улучшить ActorIterator
до некоторого CastIterator
, который позволяет вам передавать тип приведения для фильтрации в конструкторе.
Ответ №2:
Используйте переменную с именем $num_actors
, чтобы отслеживать, сколько вы уже насчитали, и break
выйти из цикла, как только вы дойдете до 3.
$num_actors = 0;
foreach ( $movies[0]->cast as $cast ) {
if ( $cast->job == 'Actor' ) {
echo '...';
$num_actors = 1;
if ( $num_actors == 3 )
break;
}
}
Комментарии:
1. Спасибо всем за помощь. Я выбрал этот здесь, потому что он показался популярным и сработал для меня.
Ответ №3:
$actors=array_filter($movies[0]->cast, function ($v) {
return $v->job == 'Actor';
});
$first3=array_slice($actors, 0, 3);
или даже
$limit=3;
$actors=array_filter($movies[0]->cast, function ($v) use (amp;$limit) {
if ($limit>0 amp;amp; $v->job == 'Actor') {
$limit--;
return true;
}
return false;
});
Ответ №4:
Добавьте счетчик и оператор if.
$count = 0;
foreach ($movies[0]->cast as $cast)
{
if ($cast->job == 'Actor')
{
echo '<p><a href="people.php?id=' . $cast->id . '">' . $cast->name . ' - ' . $cast-character . '</a></p>';
if($count >= 3)
break;
}
}
Ответ №5:
$limit = 3;
$count = 0;
foreach ($movies[0]->cast as $cast) {
// You can move the code up here if all you're getting is Actors
if ($cast->job == 'Actor') {
if ($count == $limit) break;// stop the loop
if ($count == $limit) continue;// OR move to next item in loop
$count ;
echo '<p><a href="people.php?id='
. $cast->id
. '">'
. $cast->name
. ' - '
. $cast->character
. '</a></p>';
}
}