Laravel отклонить функцию во вложенной коллекции - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь перебрать мою коллекцию, которая имеет вложенные коллекции, с функцией reject() collection и вернуть исходную коллекцию с обновленными вложенными данными.

Так что это моя коллекция викторин

{
 "id": 1,
 "title": "quiz 1",
 "questions": [
     {
         "id": 1,
         "quiz_id": 1,
         "question": "q1 - q1",
         "answers": [
             {
                 "id": 1,
                 "question_id": 1,
                 "answer": "answer to question 1"
             },
             {
                 "id": 2,
                 "question_id": 1,
                 "answer": "answer to question 1"
             }
         ]
     },
     {
         "id": 2,
         "quiz_id": 1,
         "question": "q1 - q2",
         "answers": [
             {
                 "id": 3,
                 "question_id": 2,
                 "answer": "answer to question 1"
             }
         ]
     }
 ]
}

Теперь я хочу перебрать вопросы и отклонить те, на которые уже были даны ответы и которые есть в наборе результатов. Я делаю это с помощью функции reject()

$quizResults = [
    {
        "id": 1,
        "user_id": 1,
        "quiz_id": 1,
        "question_id": 1,
        "answer_id": 1,
        "correct": 1,
        "created_at": null,
        "updated_at": null
    }
];

$filtered = $quiz->questions->reject(function ($value, $key) use ($quizResult) {
   return $quizResult->contains('question_id', $value->id);
});

Я хочу вернуть коллекцию викторин с обновленными вопросами (без отклоненных вопросов), но я не могу найти правильный способ Совершено sh это. (если я возвращаю только переменную $ отфильтрованного, я получаю правильные отфильтрованные результаты, однако, если я попытаюсь вернуть ее в переменную $ quiz, фильтр не будет применен) Если я просто сделаю

return $quiz

, я получу ту же самую оригинальную коллекцию со всеми вопросами, как если бы я никогда не выполнял функцию reject().

Как мне сделать $quiz->questions = $filtered;?

Ответы [ 3 ]

0 голосов
/ 14 февраля 2020

Передайте по ссылке

$filtered = $quiz->questions->reject(function ($value, $key) use (&$quizResult) {
   return $quizResult->contains('question_id', $value->id);
});
0 голосов
/ 15 февраля 2020

Сначала мне пришлось сбросить $ quiz ['questions'], чтобы оно выглядело так:

unset($quiz['questions']);
$quiz['questions'] = $filtered->flatten();
return $quiz;

и результат был таким, как предполагалось:

{
    "id": 1,
    "title": "quiz 1",
    "questions": [
        {
            "id": 2,
            "quiz_id": 1,
            "question": "q1 - q2",
            "answers": [
                {
                    "id": 3,
                    "question_id": 2,
                    "answer": "answer to question 1"
                }
            ]
        }
    ]
}
0 голосов
/ 14 февраля 2020

Это минимальные шаги для воспроизведения вашей проблемы,

    $quizResult = [
        0 => [
          'id' => 1,
          'user_id' => 1,
          'quiz_id' => 1,
          'question_id' => 1,
          'answer_id' => 1,
          'correct' => 1,
          'created_at' => null,
          'updated_at' => null,
        ],
    ];

    $quiz = [
        'id' => 1,
        'title' => 'quiz 1',
        'questions' => [
          0 => [
            'id' => 1,
            'quiz_id' => 1,
            'question' => 'q1 - q1',
            'answers' => [
              0 => [
                'id' => 1,
                'question_id' => 1,
                'answer' => 'answer to question 1',
              ],
              1 => [
                'id' => 2,
                'question_id' => 1,
                'answer' => 'answer to question 1',
              ],
            ],
          ],
          1 => [
            'id' => 2,
            'quiz_id' => 1,
            'question' => 'q1 - q2',
            'answers' => [
              0 => [
                'id' => 3,
                'question_id' => 2,
                'answer' => 'answer to question 1',
              ],
            ],
          ],
        ],
    ];

    $filtered = collect($quiz['questions'])->reject(function ($value) use ($quizResult) {
        return collect($quizResult)->contains('question_id', $value['id']);
    });
    $quiz['questions'] = $filtered;

    return $quiz;

И вот результат,

{
"id": 1,
"title": "quiz 1",
"questions": {
"1": {
"id": 2,
"quiz_id": 1,
"question": "q1 - q2",
"answers": [
  {
         "id": 3,
         "question_id": 2,
         "answer": "answer to question 1"
  }
 ]
}
}
}

Я не понимаю, почему вы сказали, что он возвращает оригинал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...