0

I have an array $session that I extract from an awstats file:

# Session range - Number of visits
BEGIN_SESSION 7
1h+ 10
5mn-15mn 9
0s-30s 107
2mn-5mn 7
30s-2mn 21
15mn-30mn 4
30mn-1h 11
END_SESSION

First I wanted to rearrange this by adding the two values of 0s-30s & 30s-2mn and creating another one, here's how I tried it:

$newline = "\n";
$lines = explode($newline, $session);
$results = array();
foreach ($lines as $line) {
     $parts = explode(" ", trim($line), 2);
     if (count($parts) < 2)
         continue;
     else {
         $results[$parts[0]] = intval($parts[1]);
     }
}

$temp['0s-30s'] = (isset($results['0s-30s']) ? $results['0s-30s'] : NULL);
$temp['30s-2mn'] = (isset($results['30s-2mn']) ? $results['30s-2mn'] : NULL);
$results['0s-2mn'] = $temp['0s-30s'] + $temp['30s-2mn'];
unset($results['0s-30s'], $results['30s-2mn']);
$session = $results['BEGIN_SESSION'] . $newline;
foreach ($results as $k => $v)
    $session .= $k . " " . $v . $newline;
$session .= "END_SESSION";


$session = explode("\n", $session); 
unset($session[(count($session) - 1)]); 
unset($session[0]); 
unset($session[1]);
$sessions = array();

foreach ($session as $key => $value) {
    $session[$key] = explode(" ", $value);
    $sessions[] = array($session[$key][0], trim($session[$key][1])); 
}

and it displays me this array :

Array
(
    [0] => Array
        (
            [0] => 1h+
            [1] => 10
        )

    [1] => Array
        (
            [0] => 5mn-15mn
            [1] => 9
        )

    [2] => Array
        (
            [0] => 2mn-5mn
            [1] => 7
        )

    [3] => Array
        (
            [0] => 15mn-30mn
            [1] => 4
        )

    [4] => Array
        (
            [0] => 30mn-1h
            [1] => 11
        )

    [5] => Array
        (
            [0] => 0s-2mn
            [1] => 128
        )

)

Is there a way to rearrange my array like this:

Array
(
    [0] => Array
        (
            [0] => 1h+
            [1] => 10
        )

    [1] => Array
        (
            [0] => 30mn-1h
            [1] => 11
        )

    [2] => Array
        (
            [0] => 15mn-30mn
            [1] => 4
        )

    [3] => Array
        (
            [0] => 5mn-15mn
            [1] => 9
        )

    [4] => Array
        (
            [0] => 2mn-5mn
            [1] => 7
        )

    [5] => Array
        (
            [0] => 0s-2mn
            [1] => 128
        )

)

Note: $session sometimes come with missing sessions.

2
  • Your first array and second array appear to be the same. Commented Apr 10, 2014 at 14:07
  • Sorry re-edit my post! Commented Apr 10, 2014 at 14:13

2 Answers 2

1
<?php

$session = 'BEGIN_SESSION 7
1h+ 10
5mn-15mn 9
0s-30s 107
2mn-5mn 7
30s-2mn 21
15mn-30mn 4
30mn-1h 11
END_SESSION';

$newline="\n";
$lines = explode($newline,$session);
$results = array();

foreach($lines as $line) {
    $parts = explode(" ", trim($line), 2);
    if (in_array($parts[0], array('BEGIN_SESSION', 'END_SESSION'))) continue;
    else $results[$parts[0]] = intval($parts[1]);
}

$temp['0s-30s'] = isset($results['0s-30s']) ? $results['0s-30s'] : 0;
$temp['30s-2mn'] = isset($results['30s-2mn']) ? $results['30s-2mn'] : 0;
$results['0s-2mn'] = $temp['0s-30s'] + $temp['30s-2mn'];
unset($results['0s-30s'], $results['30s-2mn']);

$order = array('0s-2mn', '2mn-5mn', '5mn-15mn', '15mn-30mn', '30mn-1h', '1h+');

uksort($results, function($a, $b) use ($order) {
    return array_search($a, $order) < array_search($b, $order);
});

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

Comments

0

The sorting is made simple by parsing the the leading integer and its following letter for later use in array_multisort() -- these characters will be enough to determine a big-endian sort. Any lines which do not contain all four needed substrings will be excluded from the result.

array_multisort() will sort by leading unit letter ASC (h before m before s), then by leading time integer DESC. Demo

$results = [];
foreach ($lines as $line) {
    if (sscanf($line, '%d%1s%s %d', $time, $unit, $tail, $count) === 4) {
        $times[] = $time;
        $units[] = $unit;
        $result[] = ["$time$unit$tail", $count];
    }
}
array_multisort($units, $times, SORT_DESC, $result);
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.