2

For a few hours, I lost myself in an array.

I have something like this:

$results = [
    "User_1" = [ 
        "Step_1" = "accepted",
        "Step_2" = "accepted",
        "Step_3" = "waiting",
        "Step_4" = "refused"
    ],
    "User_2" = [
        "Step_1" = "waiting",
        "Step_2" = "accepted",
        "Step_3" = "accepted",
        "Step_4" = "refused"
    ],
];

I need to count (and have the sum) of all the "status" for a specific "Step".

In this case, I wish to have :

$steps = [
    "Step_1" = [
        'acceptedSum' => 1,
        'refusedSum' => 0,
        'waitingSum' => 1
    ],
    "Step_2" =[
        'acceptedSum' => 2,
        'refusedSum' => 0,
        'waitingSum' => 0
    ],
    "Step_3" =[
        'acceptedSum' => 1,
        'refusedSum' => 0,
        'waitingSum' => 1
    ],
    "Step_4" =[
        'acceptedSum' => 0,
        'refusedSum' => 0,
        'waitingSum' => 2
    ],
];

Note: Number of User is not defined (1 to N) and number of Step too (1 to 4).

0

4 Answers 4

2

Try this, see if it works or not.

$steps = array();
$count = 0;
$keys = array_keys(current($results));
foreach($keys as $key){
$accepted = 0;
$refused = 0;
$waiting = 0;
foreach ($results as $result) {
    foreach ($result as $k => $v) {
        if ($key==$k&&$v == 'accepted') {
            $accepted++;
        }
        if ($key==$k&&$v == 'refused') {
            $refused++;
        }
        if ($key==$k&&$v == 'accepted') {
            $waiting++;
        }

    }
}
$new_array = [
    'acceptedSum' => $accepted,
    'refusedSum' => $refused,
    'withoutAnswerSum' => $waiting
];
$steps[$key] = $new_array;
}

print_r($steps);
Sign up to request clarification or add additional context in comments.

Comments

2

You could create the existing keys dynamically. The missing keys you could add with a value of 0;

$results = [
    "User_1" => [
        "Step_1" => "accepted",
        "Step_2" => "accepted",
        "Step_3" => "waiting"
    ],
    "User_2" => [
        "Step_1" => "waiting",
        "Step_2" => "accepted",
        "Step_3" => "accepted"
    ],
    "User_3" => [
        "Step_1" => "refused",
        "Step_2" => "refused",
        "Step_3" => "waiting"
    ]
];

$steps = [];
$status = [];

foreach ($results as $result) {
    foreach ($result as $key => $r) {
        if (!array_key_exists($key, $steps)) {
            $steps[$key] = [];
        }
        if (!array_key_exists($r."Sum", $steps[$key])) {
            $steps[$key][$r."Sum"] = 0;
        }
        $steps[$key][$r."Sum"]++;
        $status[] = $r;
    }
}

foreach (array_unique($status) as $au) {
    foreach ($steps as &$step) {
        if (!array_key_exists($au."Sum", $step)) {
            $step[$au."Sum"] = 0;
        }
    }
}

print_r($steps);

Php output demo

Comments

0

I think the output in your question is wrong, but are you looking for something like this

<?php

$results = [
    "User_1" => [
        "Step_1" => "accepted",
        "Step_2" => "accepted",
        "Step_3" => "waiting"
    ],
    "User_2" => [
        "Step_1" => "waiting",
        "Step_2" => "accepted",
        "Step_3" => "accepted"
    ],
    "User_3" => [
        "Step_1" => "refused",
        "Step_2" => "refused",
        "Step_3" => "waiting"
    ]  
];

function sumByStatus($array, $status) {
    $filtered_array = array_filter($array,function($value) use ($status) {
        return $value === $status;
    });

    return count($filtered_array);
}

$newResult = array_map(function($item) {
    return [
        'acceptedSum' => sumByStatus($item, 'accepted'),
        'refusedSumF' => sumByStatus($item, 'refused'),
        'withoutAnswerSum' => sumByStatus($item, 'waiting')
    ];
}, $results);

print_r($newResult);

The output is

Array
(
    [User_1] => Array
        (
            [acceptedSum] => 2
            [refusedSum] => 0
            [withoutAnswerSum] => 1
        )

    [User_2] => Array
        (
            [acceptedSum] => 2
            [refusedSum] => 0
            [withoutAnswerSum] => 1
        )

    [User_3] => Array
        (
            [acceptedSum] => 0
            [refusedSum] => 2
            [withoutAnswerSum] => 1
        )

)

Comments

0

Because the custom group names and their desired order are reasonably known to the developer, you can hardcode the default second level keys with 0 values in each group.

Only when a step is encountered for the first time, declare the defaults for the group. With every iteration, add one to the designated deep associative value.

Code: Demo

$defaults = array_fill_keys(['acceptedSum', 'refusedSum', 'waitingSum'], 0);
$result = [];
foreach ($results as $row) {
    foreach ($row as $k => $v) {
        $result[$k] ??= $defaults;
        ++$result[$k][$v . 'Sum'];
    }
}
var_export($result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.