Convert string to multidimensional array to calculate date in php

Viewed 101

I have a string as below

Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]

I want to break this string to multidimensional array and store days like Mon,Tue,Wed as keys and the values inside square brackets as values for each day as below and access each day as smaller arrays

Array
(
    [Mon] => [3,9]
    [Tue] => [3,9]
    [Wed] => [5,9]
    [Thu] => [5,11]
    [Fri] => [5,11]
    [Sat] => [5,11]
    [Sun] => [4,10]
)

with this below code I was able to achieve it but the value such as [3,9] or [5,11] are being treated as strings

    $atd = $utd = "";
    $dod = "20-12-2020";
    $daysArray = "Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]";
    $days = array('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
    preg_match_all("/\[[^\]]*\]/", $daysArray, $matches);
    $dayNum = $matches[0];
    $daysArray = array_combine($days , $dayNum);
    print_r($daysArray);
        
        $valArray = array();
        
        foreach($daysArray as $day=>$val){
            if($day == "Mon" || $day == "Tue"){
              $atd = date("d-m-Y", strtotime("+".$val[0]." days", $dod));
              $utd = date("d-m-Y", strtotime("+".$val[1]." days", $dod));
           }else if($day == "Sun"){
              $atd = date("d-m-Y", strtotime("+".$val[0]." days", $dod));
              $utd = date("d-m-Y", strtotime("+".$val[1]." days", $dod));
           }else if($day == "Wed"){
              $atd = date("d-m-Y", strtotime("+".$val[0]." days", $dod));
              $utd = date("d-m-Y", strtotime("+".$val[1]." days", $dod));
           }else{
              $atd = date("d-m-Y", strtotime("+".$val[0]." 5 days", $dod));
              $utd = date("d-m-Y", strtotime("+".$val[1]." days", $dod));
             }
            }
        } 

when I print $valArray it is a array like below which is very bad.

array(
   [0]=>[
   [1]=>4
   [2]=>,
   [3]=>1
   [4]=>0
   [5]=>]
);

Please help

5 Answers

Try this:

$str = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';
// convert main string to array by explode by empty space
$arr = explode(' ', $str);

$newArr = [];

foreach ($arr as $data) {
  // to get all b/n brackets best is to use regEx
  preg_match('#\[(.*?)\]#', $data, $match);
  // for key of new array use all befor 1st bracket
  // and for content explode data b/n brackets by ','
  $newArr[strtok($data, '[')] = explode(',', $match[1]);
}

var_dump($newArr);

Result:

array(7) {  ["Mon"]=> array(2) { [0]=> string(1) "3" [1]=> string(1) "9" } 
            ["Tue"]=> array(2) { [0]=> string(1) "3" [1]=> string(1) "9" }    
            ["Wed"]=> array(2) { [0]=> string(1) "5" [1]=> string(1) "9" } 
            ["Thu"]=> array(2) { [0]=> string(1) "5" [1]=> string(2) "11" } 
            ["Fri"]=> array(2) { [0]=> string(1) "5" [1]=> string(2) "11" } 
            ["Sat"]=> array(2) { [0]=> string(1) "5" [1]=> string(2) "11" } 
            ["Sun"]=> array(2) { [0]=> string(1) "4" [1]=> string(2) "10" } 
    }

I think this is the result you were asking for.

$str = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';

$result = [];

$bits = explode(' ', $str); // explode on space between day names
foreach ( $bits as $bit) {
    $b = explode('[', $bit);    // $bit = Mon[3,9] 
    $b[1] = rtrim($b[1], ']');  // $b0 = Mon, B1 = 3,9] so trim off the last ]
    $result[$b[0]] = explode(',', $b[1]); // explode on , to get inner array
}
print_r($result);

Result

Array
(
    [Mon] => Array
        (
            [0] => 3
            [1] => 9
        )
    [Tue] => Array
        (
            [0] => 3
            [1] => 9
        )
    [Wed] => Array
        (
            [0] => 5
            [1] => 9
        )
    [Thu] => Array
        (
            [0] => 5
            [1] => 11
        )
    [Fri] => Array
        (
            [0] => 5
            [1] => 11
        )
    [Sat] => Array
        (
            [0] => 5
            [1] => 11
        )
    [Sun] => Array
        (
            [0] => 4
            [1] => 10
        )
)

Here's a suggestion:

$days = "Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]";
$individualDays = explode(' ', $days);
$result = [];
foreach ($individualDays as $individualDay) {
    $dates = preg_match_all('/\d+/', $individualDay, $matches);
    $result[substr($individualDay, 0, 3)] = $matches[0];
}

How it works:

  • All your values are separated by a space, so we first explode by it to get an array of individual strings (Mon[3,9], Tue[3,9] and so on) we can iterate.
  • The first three characters of each of those strings are the day designation and we use that as the key for our new resulting array (utilizing substr).
  • We match all numbers in preg_match_all and assign the array of matches to that key.

You might also use a pattern to match the individual parts using capturing groups and preg_replace_callback.

Pass an array by reference to the callback to set the group 1 value as the key, and an array with the values of group 2 and group 3.

([a-z]+)\[(\d+),(\d+)]

Explanation

  • ([a-z]+) Capture group 1, match 1+ a char a-z
  • \[ Match [
  • (\d+),(\d+) Capture 1+ digits in capture group 2 and group 3 and match a , in between
  • ] Match closing ]

See a regex demo and a Php demo

Example using a case insensitive match /i

$pattern = '/([a-z]+)\[(\d+),(\d+)]/i';
$str = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';
$result = [];

preg_replace_callback(
    $pattern,
    function ($m) use (&$result) {
        $result[$m[1]] = [$m[2], $m[3]];
    },
    $str
);

print_r($result);

Output

Array
(
    [Mon] => Array
        (
            [0] => 3
            [1] => 9
        )

    [Tue] => Array
        (
            [0] => 3
            [1] => 9
        )

    [Wed] => Array
        (
            [0] => 5
            [1] => 9
        )

    [Thu] => Array
        (
            [0] => 5
            [1] => 11
        )

    [Fri] => Array
        (
            [0] => 5
            [1] => 11
        )

    [Sat] => Array
        (
            [0] => 5
            [1] => 11
        )

    [Sun] => Array
        (
            [0] => 4
            [1] => 10
        )

)

This solution converts the string to a JSON string by replacing characters. To create the desired array, only one json_decode() is necessary.

$input = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';

$strJson = '{"'.strtr($input,[" " => ',"','[' => '":['])."}";
$array = json_decode($strJson, true);

//test output
echo "<pre>".var_export($array, true)."/<pre>";
Related