Home > front end >  Group rows of data by column value then store nested data, first and last occurrences, and counts wi
Group rows of data by column value then store nested data, first and last occurrences, and counts wi

Time:01-27

I am trying to split an array of space-delimited strings, group by a particular column, then store the data within each group in a more convenient structure.

Sample data:

$dataArray = [
    0 => "AAAAA 2023 01 25 01:04:00 ID:20fjrjeZZ",
    1 => "AAAAA 2023 01 25 01:18:08 ID:13454B43A",
    2 => "AAAAA 2023 01 25 02:00:02 ID:18f5hjeWe",
    3 => "AAAAA 2023 01 25 04:10:13 ID:13454B43A",
    4 => "BBBBB 2023 01 25 01:44:10 ID:Xj74320fj",
    5 => "BBBBB 2023 01 25 07:08:58 ID:13454B43A",
    6 => "BBBBB 2023 01 25 08:40:52 ID:Ftzkk800Y",
    7 => "BBBBB 2023 01 25 14:10:13 ID:18f5hjeWe"
];

I split the rows on the space with:

$lines = explode(' ', $dataArray);

Then I want to push the individual parts (AAAA, 2023, 01, ...) into an array.

foreach($dataArray as $parts){
    $spotArray[] = $parts[$parts][0];
    $yearArray[] = $parts[$parts][1];
    // ...
}

Then build a new structure with the new array parts:

foreach($dataArray as $key => $value){
    $desiredArray[] = $spotArray[["user"[$yearArray[$hourArray]]], "first"[/** ... */]];
    //...
}

Expected result:

$desiredArray = [
    "AAAAA" => [
        "user" => [
            "ID:20fjrjeZZ" => ["01:04:00"],
            "ID:13454B43A" => ["01:18:08", "04:10:12"],
            "ID:18f5hjeWe" => ["02:00:02"]
        ],
        "first" => "01:04:00",
        "last" => "04:10:12",
        "totaUser" => 3,
        "totalAccess" => 4
    ],
    "BBBBB" => [
        "user" => [
            "ID:Xj74320fj" => ["01:44:10"],
            "ID:13454B43A" => ["07:08:58"],
            "ID:Ftzkk800Y" => ["08:40:52"],
            "ID:18f5hjeWe" => ["14:10:13"]
        ],
        "first" => "01:44:10",
        "last" => "14:10:13",
        "totaUser" => 4,
        "totalAccess" => 4
    ]
];

CodePudding user response:

You can find the answer to your question here

<?php

$dataArray = [
        0 => "AAAAA 2023 01 25 01:04:00 ID:20fjrjeZZ",
        1 => "AAAAA 2023 01 25 01:18:08 ID:13454B43A",
        2 => "AAAAA 2023 01 25 02:00:02 ID:18f5hjeWe",
        3 => "AAAAA 2023 01 25 04:10:13 ID:13454B43A",
        4 => "BBBBB 2023 01 25 01:44:10 ID:Xj74320fj",
        5 => "BBBBB 2023 01 25 07:08:58 ID:13454B43A",
        6 => "BBBBB 2023 01 25 08:40:52 ID:Ftzkk800Y",
        7 => "BBBBB 2023 01 25 14:10:13 ID:18f5hjeWe"
    ];
    
$finalArr = array();
$count_arr = array();
$count_arr1 = array();
foreach($dataArray as $parts){    
    $lines = explode(' ', $parts);
    $finalArr[$lines[0]]['user'][$lines[5]][] = $lines[4];
    $count_arr1[$lines[0]]['user'][$lines[5]] = $lines[4];
    $count_arr[$lines[0]][] = 1;

}
foreach($finalArr as $key => $parts){   
    $finalArr[$key]['first'] = reset($count_arr1[$key]['user']);
    $finalArr[$key]['last'] = end($count_arr1[$key]['user']);
    $finalArr[$key]['totaUser'] = count($finalArr[$key]['user']);
    $finalArr[$key]['totalAccess'] = count($count_arr[$key]);
}
print_r($finalArr);

CodePudding user response:

It is not at all necessary to run two loops.

Parse the space-delimited strings in your array and build/overwrite/sum as you iterate.

Code: (Demo)

foreach ($dataArray as $row) {
    [$group, $y, $m, $d, $t, $id] = explode(' ', $row);
    $result[$group]['user'][$id][] = $t;  // accumulate nested elements
    $result[$group]['first'] ??= $t; // only store the first occurrence
    $result[$group]['last'] = $t; // keep overwriting each time
    $result[$group]['totaluser'] = count($result[$group]['user']); // count what is accumulated
    $result[$group]['totalAccess'] = ($result[$group]['totalAccess'] ?? 0)   1; // increment
}
var_export($result);

You can even safely remove the unused $y, $m, and $d declarations if you wish. (Demo)

  • Related