首页 > 解决方案 > PHP根据当前数组键取消移位和推送值

问题描述

我有一个测验,您可以在其中使用文本字段或单选按钮来获得答案。答案存储在数据库中。不需要任何答案,因此人们可以跳过问题。

每个条目存储在一行中:

Array
(
    [0] => Array
        (
            [0] => Dave
            [1] => ok
            [2] => Manchester
            [3] => No
        )

    [1] => Array
        (
            [0] => James
            [1] => Happy
            [2] => London
            [3] => Yes
        )

    [2] => Array
        (
            [0] => Victoia
            [2] => Leeds
        )

)

目前,问题编号由键表示。所以 Victoria 没有回答问题 1 或 3。我的目标是将未回答的问题添加到数组中,并且正确的键值为 null。

到目前为止,这是我的代码,但我正在努力使数组键位置正确:

$answersArr = (array) $answers;
$row = array();
$items = array();
$numberOfQuesitons = count($headers);

foreach ($answersArr as $key=>$result) {
    $answer = json_decode(stripslashes($result->answers));
    $row[$key] = (array) $answer;
    $single = count($row[$key]);
    $currentKey = key($row[$key]);

    for ($i = $single ; $i < $numberOfQuesitons; $i++) {
        if ($numberOfQuesitons - $i > 0) {
            if ($currentKey > 0) {
                array_unshift($row[$key], null);
            } else {
                array_push($row[$key], null);
            }
        }
    }
}

print_r($row);

我得到的输出:

Array
(
    [0] => Array
        (
            [0] => Admin
            [1] => ok
            [2] => Manchester
            [3] => No
        )

    [1] => Array
        (
            [0] => Rod
            [1] => Happy
            [2] => London
            [3] => Yes
        )

    [2] => Array
        (
            [0] => Rozi
            [2] => Leeds
            [3] => 
            [4] => 
        )

)

数组中的最后一行需要如下所示:

[2] => Array
        (
            [0] => Victoia
            [1] => 
            [2] => Somewhere
            [3] => 
        )

有点卡在这里任何帮助将不胜感激。

谢谢

标签: phparrays

解决方案


让我说我通读了您的代码并且必须做出两个假设$numberOfQuesitons = 4$single = 2Victoia. 假设是基于人名包含在结果数组中,否则无法派生的事实。

因此,在您的 Vittoia 迭代代码中,我们将使用以下数组:

$row[$key] = [
    0 => 'Victoia',
    2 => 'Leeds',
];

然后在内部 for 循环将发生以下情况(如注释中所述):

for ($i = $single; $i < $numberOfQuesitons; $i++) {
    // 4 - 2 = 2, 2 > 0 = true <-- first iteration
    // 4 - 3 = 1, 1 > 0 = true <-- second (and final) iteration
    if ($numberOfQuesitons - $i > 0) {
        // $currentKey doesn't change in this process
        // and since the key is taken from the array
        // $row[$key] points to, the key function will return 0 each iteration.
        if ($currentKey > 0) {
            // Also note that unshift will only add elements to the front of the array.
            array_unshift($row[$key], null);
        } else {
            // Hence we drop down in this branch of the if statemtent
            // as 0 > 0 evaluates to false each evaluation.
            // So we start with [0] => Rozi || Victoia
            //                  [2] => Leeds || Somewhere
            // Push null thus:  [3] => null
            // Push null thus:  [4] => null
            // Hence our final result.

            // Also note that push only 'pushes' elements at the end of the array.
            array_push($row[$key], null);
        }
    }
}

为了解决这个问题,我们可以稍微改变一下逻辑,但我个人会将嵌套循环修改为以下(或类似的东西):

$answersArr = (array) $answers;
$row = array();
$numberOfQuesitons = count($headers);

foreach ($answersArr as $key => $result) {
    $answer = json_decode(stripslashes($result->answers));
    $row[$key] = (array) $answer;

    // We simply create a range from 0 up to the last question number.
    $all = range(0, $numberOfQuesitons - 1);
    // Taking the difference between all questions and the answered
    // ones will give us the missing ones.
    $unAnsweredQs = array_diff($all, array_keys($row[$key]));

    // Add those missing questions to the array.
    foreach ($unAnsweredQs as $unAnswered) {
        // Or maybe a more appropriate default.
        $row[$key][$unAnswered] = null;
    }

    // Sort the keys, such that we respect the wanted order
    // Name (key 0), Q1, Q2, ..., QN
    ksort($row[$key]);
}

print_r($row);

推荐阅读