Экстракт соединенной результирующего набора в иерархии родитель-потомок


Я пишу приложение викторина на PHP и запросов к БД для вопросов и соответствующих ответов. Тогда я пересекаюсь результирующий набор в массив полезной на мой передний конец. Однако, это всегда похоже на поединок и мне интересно, если я мог добраться до моей желаемой структуры массива более эффективно.

То, что я хотел был ассоциативный массив / словарь, который был структурирован так, что вопросы были на высшем уровне и связанные с ними ответы внизу. Я также хотел числового индекса выше вопрос, так что я могу потом использовать это, чтобы соответствовать моим current_step сессии переменная для перебора форме.

function get_question_data( $quiz_id)
{
    global $wpdb;

    if ( !isset($quiz_id)) {
        return FALSE;
    }

    $sql = $wpdb->prepare("SELECT q.ID AS 'question_id', question, explanation, q.sort_order, qa.ID AS 'answer_id', qa.answer, qa.correct, qa.hint
                           FROM {$wpdb->prefix}my_quiz_questions q
                           LEFT JOIN wp_nmsi_quiz_answers AS qa ON q.ID = qa.question_id
                           WHERE quiz_id=%d ORDER BY q.ID", $quiz_id);
    $quiz_data = $wpdb->get_results($sql, ARRAY_A);
    fb($quiz_data,'DATABASE RESULTS');

    //build into a user-friendly array which we can use to manage quiz steps and questions later.
    $question_array = array();

    foreach ($quiz_data as $key=>$value) {


      foreach ($value as $k => $v) {
            if ($k == 'question' ) {
                if (!array_key_exists('question_'.$value['question_id'], $question_array)) {
                $question_array['question_'.$value['question_id']]['question_text'] = $v;
                $question_array['question_'.$value['question_id']]['question_id'] = $value['question_id'];
                }
            }

            if ($k == 'answer'){
                $question_array['question_'.$value['question_id']]['answers'][$value['answer_id']]['text'] = $v;        
            }

            if ($k == 'hint') {
                $question_array['question_'.$value['question_id']]['answers'][$value['answer_id']]['hint'] = $v;
            }

            if ($k == 'correct') {
                $question_array['question_'.$value['question_id']]['answers'][$value['answer_id']]['correct'] = $v;
            }


            if ($k == 'explanation' ) {
                $question_array['question_'.$value['question_id']]['explanation'] = $v;
            }

        }


    }

    //echo $wpdb->last_query;
    return array_values($question_array);
}

Я закончил с этим решением.

Обновление: Результаты Запроса

array(6) {
  [0]=>
  array(8) {
    ["question_id"]=>
    string(1) "1"
    ["question"]=>
    string(34) "Question 1. What is the question ?"
    ["explanation"]=>
    string(38) "This is the explanation for question 1"
    ["sort_order"]=>
    string(1) "0"
    ["answer_id"]=>
    string(2) "20"
    ["answer"]=>
    string(16) "this is answer 4"
    ["correct"]=>
    string(1) "0"
    ["hint"]=>
    string(29) "this is the hint for answer 4"
  }
  [1]=>
  array(8) {
    ["question_id"]=>
    string(1) "1"
    ["question"]=>
    string(34) "Question 1. What is the question ?"
    ["explanation"]=>
    string(38) "This is the explanation for question 1"
    ["sort_order"]=>
    string(1) "0"
    ["answer_id"]=>
    string(2) "19"
    ["answer"]=>
    string(16) "this is answer 3"
    ["correct"]=>
    string(1) "0"
    ["hint"]=>
    string(29) "this is the hint for answer 3"
  }
  [2]=>
  array(8) {
    ["question_id"]=>
    string(1) "1"
    ["question"]=>
    string(34) "Question 1. What is the question ?"
    ["explanation"]=>
    string(38) "This is the explanation for question 1"
    ["sort_order"]=>
    string(1) "0"
    ["answer_id"]=>
    string(2) "18"
    ["answer"]=>
    string(16) "this is answer 2"
    ["correct"]=>
    string(1) "0"
    ["hint"]=>
    string(29) "this is the hint for answer 2"
  }
  [3]=>
  array(8) {
    ["question_id"]=>
    string(1) "1"
    ["question"]=>
    string(34) "Question 1. What is the question ?"
    ["explanation"]=>
    string(38) "This is the explanation for question 1"
    ["sort_order"]=>
    string(1) "0"
    ["answer_id"]=>
    string(2) "17"
    ["answer"]=>
    string(16) "this is answer 1"
    ["correct"]=>
    string(1) "1"
    ["hint"]=>
    string(29) "this is the hint for answer 1"
  }
  [4]=>
  array(8) {
    ["question_id"]=>
    string(1) "2"
    ["question"]=>
    string(10) "Question 2"
    ["explanation"]=>
    string(26) "Explanation for question 2"
    ["sort_order"]=>
    string(1) "0"
    ["answer_id"]=>
    string(2) "24"
    ["answer"]=>
    string(28) "test answer 2 for question 2"
    ["correct"]=>
    string(1) "0"
    ["hint"]=>
    string(13) "answer 2 hint"
  }
  [5]=>
  array(8) {
    ["question_id"]=>
    string(1) "2"
    ["question"]=>
    string(10) "Question 2"
    ["explanation"]=>
    string(26) "Explanation for question 2"
    ["sort_order"]=>
    string(1) "0"
    ["answer_id"]=>
    string(2) "23"
    ["answer"]=>
    string(28) "test answer 1 for question 2"
    ["correct"]=>
    string(1) "1"
    ["hint"]=>
    string(13) "answer 1 hint"
  }
}


342
5
задан 8 февраля 2011 в 12:02 Источник Поделиться
Комментарии
2 ответа

Первый отрезок: так как каждая строка содержит такой же набор полей, вы можете почистить код значительно пропустив внутреннего цикла.

$question_array = array();
foreach ($quiz_data as $row) {
$qId = $row['question_id'];
$aId = $row['answer_id'];
$answer = array(
'id' => $aId,
'text' => $row['answer'],
'hint' => $row['hint'],
'correct' => $row['correct'],
);
if (!array_key_exists($qId, $question_array)) {
$question_array[$qId] = array(
'id' => $qId,
'text' => $row['question'],
'explanation' = $row['explanation'],
'sort' = $row['sort_order'],
);
}
$question_array[$qId]['answers'][$aId] = $answer;
}

Второй отрезок: использовать объекты, а не массивы. Хотя это может показаться не окупиться сначала, как вы начнете выполнять более сложные операции по Вопросы и ответы вы сможете получить многое от заключения.

$question_array = array();
foreach ($quiz_data as $row) {
$qId = $row['question_id'];
$answer = new Answer($row['answer_id'], $row['answer'], $row['hint'], $row['correct']);
if (!array_key_exists($qId, $question_array)) {
$question_array[$qId] = $question
= new Question($qId, $row['question'], $row['explanation'], $row['sort_order']);
}
else {
$question = $question_array[$qId];
}
$question->addAnswers($answer);
}

Вот несколько самых основных определений классов вопрос и ответ, чтобы вы начали.

class Question {
private $id;
private $text;
private $explanation;
private $sortOrder;
private $answers = array();
public function __construct($id, $text, $explanation, $sortOrder) {
$this->id = $id;
$this->text = $text;
$this->explanation = $explanation;
$this->sortOrder = $sortOrder;
}
public addAnswer(Answer $answer) {
$this->answers[$answer->getId()] = $answer;
}
... property accessors and other methods ...
}

class Answer {
private $id;
private $text;
private $hint;
private $correct;
public function __construct($id, $text, $hint, $correct) {
$this->id = $id;
$this->text = $text;
$this->hint = $hint;
$this->correct = $correct;
}
... property accessors and other methods ...
}

3
ответ дан 11 февраля 2011 в 03:02 Источник Поделиться

От структуры SQL-запроса, похоже, что ваш выход будет иметь повторяющиеся строки, из-за того, что на один вопрос может быть несколько ответов. Это означает, что вы будете иметь, чтобы сделать некоторые поддатые вещи, как то, что вы сделали с вложенные циклы foreach петли. Я бы рекомендовал разделять это на два отдельных запроса, один к вам вопросы и получать ответы, а потом просто ставишь ответы прямо в массив без всяких если(ключ==что-то) { // присвоить что-то } волшебство.

Что касается самого выбора, это выглядит довольно хорошо. Некоторые незначительные моменты:


  1. question_array не нужно иметь строка ключа (например, $question_array['question_1']); это может быть легче работать, если вы просто использовать цифры (например, $question_array[1]).

  2. У вас нет поля, сколько очков каждый вопрос стоит.

0
ответ дан 8 февраля 2011 в 05:02 Источник Поделиться