====== valueList() ======

''array **valueList**(string //Fragekennung//, [array //Items//], [string //Ausgabeformat//])''\\
''array **valueList**(array //Variablen//, [null], [string //Ausgabeformat//])''\\
''array **valueList**(string //Systemkennung//)''

Die Funktion valueList() ruft für alle //Items// einer Frage -- oder für alle Items einer Frage, wenn keine Items angegeben werden -- die Antwortcodes ab. Alternativ kann auch eine Liste von //Variablen// angegeben werden, für welche die Antwortcodes abgerufen werden.

  * //Fragekennung//\\ Die Kennung einer Frage im **Fragenkatalog**.
  * //Items//\\ Optional kann eine Liste von Items angegeben werden. Werden keine Items angegeben, verwendet die Frage alle Items der Frage.
  * //Variablen//\\ Anstatt einer Fragekennung kann auch eine Liste von Variablen angegeben werden,\\ z.B. ''valueList(array('AB01', 'AB02_01', 'AB02_02'))''
  * //Systemkennung//\\ Die Kennung '''TIME''' ruft die Verweildauer der Seiten (//TIME001//, //TIME002//, etc.) als Array mit Seitenzahlen als Index und Verweildauer [Sekunden] als Wert ab.
  * //Ausgabeformat//\\ Mit dem Ausgabeformat wird festgelegt, ob die Funktion den Antwort-Code (Standard) oder den Beschriftungstext der Antwort zurückgibt. Es sind die gleichen Angaben möglich wie bei ''[[de:create:functions:value]]''.

===== Rückgabewert =====

Die Funktion ''valueList()'' gibt ein assoziatives Array zurück. Die Kennungen der Variablen dienen als Schlüssel, die Antwortcodes für die Items als Werte, z.B.

<code php>
array(
  'AB01' => 3,
  'AB02_01' => -1,
  'AB02_02' => 2
)
</code>


===== Zufallsgenerator =====

Eine häufige Anwendung der Funktion '''valueList()'' erfolgt in Zusammenhang mit einem [[:de:create:questions:random]], der mehrere Zettel pro Interview zieht.

Der folgende PHP-Code ermittelt die Codes aller im Zufallsgenerator "IV01" gezogenen Zettel als [[:de:create:array|Array]].

<code php>
$codes = valueList('IV01');
</code>

Der folgende Code ließt die Beschriftungen der gezogenen Zettel anstatt derer numerischer Codes aus:

<code php>
$codes = valueList('IV01',  null, 'label');
</code>


===== Items mit der höchsten Bewertung =====

Ein anderes Anwendungsbeispiel für ''valueList()'' ist die Auswahl von Items ... und zwar nicht mit einem fixen Kriterium wie bei ''[[:de:create:functions:getitems]]'', sondern z.B. die drei Items mit den höchsten Bewertungen.

Nehmen wir als Beispiel eine Batterie aus Schiebreglern (Frage vom Typ //Schieberegler//, z.B. "SR01") mit 15 Items. In einer Folgefrage sollen dann nur jene drei Items vertieft werden, welche vom Teilnehmer die höchste Bewertung (z.B. Nutzungsmenge) erhalten haben.

Mit ''valueList()'' wird zunächst eine Liste aller Antworten abgerufen. Anschließend wird diese Liste absteigend sortiert -- und zwar mittels ''[[https://www.php.net/manual/de/function.arsort.php|arsort()]]'', damit die Zuordnung von Variablen-Kennung und Wert erhalten bleibt.

<code php>
$values = valueList('SR01');
arsort($values);
</code>

In der Variable ''$values'' könnte nun z.B. folgendes stehen:

^Schlüssel^Wert^
|SR01_07|  101|
|SR01_02|  63|
|SR01_04|  59|
|SR01_15|  59|
|SR01_10|  42|
|SR01_11|  38|
|SR01_05|  35|
|SR01_14|  32|
|...|  ...|

**Vorsicht:** Es kann nun passieren, dass das dritte und vierte Item (im Beispiel oben "SR01_04" und "SR01_15") den gleichen Wert bekommen haben. Man muss entscheiden, wie man mit diesem Fall umgeht: Soll das vierte Item in der Folgefrage mit auftauchen? Soll zufällig nur eines der Items verwendet werden?

Für dieses Beispiel sollen immer genau drei Items abgefragt werden, es muss also zufällig eines der beiden Items ausgewählt werden. Das ist nicht ganz trivial. Dafür wird die Liste in drei Teile geteilt: Items, die einen höheren Wert als das dritte Item (''SR01_04 => 59'', ''$threshold'') erreichen (''$greater''), Items, die genau diesen Wert erreichen (''$equal'') und Items, die einen geringeren Wert erreichen. Die letzte Liste benötigen wir nicht mehr.

<code php>
$order = array_keys($values);
$threshold = $values[$order[2]];
$greater = array();
$equal = array();
foreach ($values as $varID => $value) {
  $itemID = (int)ltrim(substr($varID, 5), "0");
  if ($value > $threshold) {
    $greater[] = $itemID;
  } elseif ($value == $threshold) {
    $equal[] = $itemID;
  }
}
</code>

Zur Erklärung von ''$threshold'': Die Variable ''$order'' enthält die Schlüssel des Arrays ''$values''. Damit kann man gezielt den Schlüssel des dritten Werts (Index 2) in der sortierten Liste abrufen. ''$order[2]'' wäre hier also "SR01_04" und wenn man diesen Schlüssel aus ''$values'' abruft, bekommt man im Beispiel die ''59''.

Zur Erklärung vin ''$itemID'': Wir benötigen ja nicht die komplette Variablen-Kennung (z.B. "SR01_01"), sondern nur die Nummer des Items, also z.B. ''1''. Dafür entnehmen wir zunächst mittels ''substr()'' aus "SR01_01" alles ab der sechsten Position (Index 5), also "01", und dann wird mittels ''ltrim()'' noch die führende "0" entfernt, damit PHP den Text "1" anschließend mittels ''(int)'' in die Zahl ''1''.

Das Mischen der Liste ''$equal'' erfolgt mittels ''shuffle()''. Und aus dieser Liste benötigen wir drei minus die Anzahl Elemente aus der Liste ''$greater'', ermittelt via ''count()''.

<code php>
shuffle($equal);
$needed = 3 - count($greater);
$items = array_merge($greater, array_slice($equal, 0, $needed));
</code>

Die Liste $items enthält nun die Nummern der Top 3 Items, also entweder ''7,2,4'' oder ''7,2,15''. Diese können nun in einer Folgefrage, welche die gleichen 15 Items enthält wie die Frage "SR01" mittels ''question()'' abgefragt werden.

<code php>
question('FF02', $items);
</code>

Der gesamte PHP-Code sieht dann wie folgt aus.

<code php>
$values = valueList('SR01');
arsort($values);

$order = array_keys($values);
$threshold = $values[$order[2]];
$greater = array();
$equal = array();
foreach ($values as $varID => $value) {
  $itemID = (int)ltrim(substr($varID, 4), "0");
  if ($value > $threshold) {
    $greater[] = $varID;
  } elseif ($value == $threshold) {
    $equal[] = $varID;
  }
}

shuffle($equal);
$needed = 3 - count($greater);
$items = array_merge($greater, array_slice($equal, 0, $needed));

question('FF02', $items);
</code>