Sorting elements from string

Hi Experts!

I've got a string like so:
$str = '2009,(1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849,2010,(4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182,2011,(12)1244,(13)1447,(34)3716';

Open in new window

And I need to sort it, so the final output would be sort by year (four digits between commas, no brakets in above string) and numbers with brakets would be moved from front to the back of the main number, so result should look like this:
$y2009 = '110(1),612(6),718(7),2416(20),3058(25),3849(30)';
$y2010 = '431(4),876(7),2058(17),5036(42),5248(44),6182(51)';
$y2011 = '1244(12),1447(13),3716(34)';

Open in new window

I probably need to play with 'explode' and 'preg_replace' functions, but not sure how, please help.

Thanks.
LVL 8
ZadoAsked:
Who is Participating?
 
Lukasz ChmielewskiConnect With a Mentor Commented:
<?php

    error_reporting(E_ERROR);

    function trimch($str){
        return trim($str,",");
    }

    function multipleExplode($delimiters = array(), $string = ''){ 

         $mainDelim=$delimiters[count($delimiters)-1]; // dernier 
         
         array_pop($delimiters); 
         
         foreach($delimiters as $delimiter){ 
         
             $string= str_replace($delimiter, $mainDelim, $string); 
         
         } 

         $result= explode($mainDelim, $string); 
         return $result; 

     }

	$str = '2009,(1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849,2010,(4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182,2011,(12)1244,(13)1447,(34)3716';
	
    $pattern = '/^\d{4}|\,\d{4}/';
    preg_match_all($pattern, $str, $matches);
    
    // here we explode by year
    $test = multipleExplode($matches[0], $str);
    // remove the first empty element
    array_shift($test);
    
    // remove commas
    $years = array_map(trimch,$matches[0]);
    
    //trim commas from exploded strings
    $strs = array_map(trimch,$test);
    
    //print_r($years);
    //print_r($strs);
    
    $values = array();
    
    // let's sort the strings
    foreach($strs as $val){
        
        // explode the string with ,
        $array = explode(",",$val);
        
        $line = "";
        
        // reverse the bracket number with the number
        foreach($array as $piece){
            
            $tmp_string = explode(")",$piece);
            $tmp_string = $tmp_string[1].$tmp_string[0]."),";
            $line .= $tmp_string;
            
        }
        $line = trim($line,",");        
        $values[] = $line;
    }
    
    $result = array_combine($years,$values);
    
    //print_r($result);
    
    foreach($result as $key => $val){
        $str = "y".$key;
        $$str = $val;
        
        echo"the variable $str equals $val<br />";
    }
    
    // AND JUST TO MAKE SURE:
    echo $y2009."<br />";
    echo $y2010."<br />";
    echo $y2011."<br />";
    
?>

Open in new window

0
 
Lukasz ChmielewskiCommented:
I'll post back in a second
but here's what I have so far:

<?php

    error_reporting(E_ERROR);

    function trimch($str){
        return trim($str,",");
    }

    function multipleExplode($delimiters = array(), $string = ''){ 

         $mainDelim=$delimiters[count($delimiters)-1]; // dernier 
         
         array_pop($delimiters); 
         
         foreach($delimiters as $delimiter){ 
         
             $string= str_replace($delimiter, $mainDelim, $string); 
         
         } 

         $result= explode($mainDelim, $string); 
         return $result; 

     }

	$str = '2009,(1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849,2010,(4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182,2011,(12)1244,(13)1447,(34)3716';
	
    $pattern = '/^\d{4}|\,\d{4}/';
    preg_match_all($pattern, $str, $matches);
    
    // here we explode by year
    $test = multipleExplode($matches[0], $str);
    
    // remove commas
    $years = array_map(trimch,$matches[0]);
    
    //trim commas from exploded strings
    $strs = array_map(trimch,$test);
    
    print_r($matches);
    print_r($strs);
    
?>

Open in new window

0
 
ZadoAuthor Commented:
Ok, I will wait for final result, thanks for your help!
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
Lukasz ChmielewskiCommented:
Ok getting close:

<?php

    error_reporting(E_ERROR);

    function trimch($str){
        return trim($str,",");
    }

    function multipleExplode($delimiters = array(), $string = ''){ 

         $mainDelim=$delimiters[count($delimiters)-1]; // dernier 
         
         array_pop($delimiters); 
         
         foreach($delimiters as $delimiter){ 
         
             $string= str_replace($delimiter, $mainDelim, $string); 
         
         } 

         $result= explode($mainDelim, $string); 
         return $result; 

     }

	$str = '2009,(1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849,2010,(4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182,2011,(12)1244,(13)1447,(34)3716';
	
    $pattern = '/^\d{4}|\,\d{4}/';
    preg_match_all($pattern, $str, $matches);
    
    // here we explode by year
    $test = multipleExplode($matches[0], $str);
    // remove the first empty element
    array_shift($test);
    
    // remove commas
    $years = array_map(trimch,$matches[0]);
    
    //trim commas from exploded strings
    $strs = array_map(trimch,$test);
    
    //print_r($years);
    //print_r($strs);
    
    $values = array();
    
    // let's sort the strings
    foreach($strs as $val){
        
        // explode the string with ,
        $array = explode(",",$val);
        
        $line = "";
        
        // reverse the bracket number with the number
        foreach($array as $piece){
            
            $tmp_string = explode(")",$piece);
            $tmp_string = $tmp_string[1].$tmp_string[0]."),";
            $line .= $tmp_string;
            
        }
        $line = trim($line,",");        
        $values[] = $line;
    }
    
    $result = array_combine($years,$values);
    
    print_r($result);
    
?>

Open in new window

0
 
Ray PaseurConnect With a Mentor Commented:
No matter what you do with the program code, you are going to come up with a brittle design.  This almost looks like XML with the markup removed.  I think I might not go the extra step to assigning local variables.  Since the data appears to be related by year it would make more sense to me to keep it in an array.  You might rtrim() the array values.
http://www.laprbass.com/RAY_temp_zado.php

Outputs something like
Array
(
    [2009] => (1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849,
    [2010] => (4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182,
    [2011] => (12)1244,(13)1447,(34)3716,
)
string(47) "(1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849"
string(49) "(4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182"
string(26) "(12)1244,(13)1447,(34)3716"

HTH, ~Ray
<?php // RAY_temp_zado.php
error_reporting(E_ALL);
echo "<pre>";

// ALLOW THE USE OF STRTOTIME() TO DETECT YEARS
date_default_timezone_set('America/Chicago');

// THE TEST DATA
$str = '2009,(1)110,(6)612,(7)718,(20)2416,(25)3058,(30)3849,2010,(4)431,(7)876,(17)2058,(42)5036,(44)5248,(51)6182,2011,(12)1244,(13)1447,(34)3716';

// BREAK THE TEST DATA BY REMOVING COMMAS
$arr = explode(',', $str);

// SET A SIGNAL STRING
$yrs = '?';

// USE AN ITERATOR TO COVER THE ARRAY
foreach ($arr as $num)
{
    // IF IT LOOKS LIKE A YEAR
    if (strtotime($num))
    {
        // START A NEW ELEMENT OF THE ARRAY
        $out[$num] = NULL;
        $yrs = $num;
    }
    else
    {
        // APPEND TO THIS ELEMENT OF THE ARRAY
        $out[$yrs] .= $num . ',';
    }
}

// SHOW THE WORKING ARRAY
print_r($out);

// CONVERT THE ARRAY INTO LOCAL STRINGS
foreach ($out as $yrs => $nms)
{
    // CREATE A VARIABLE NAME AND ASSIGN THE STRING
    $ndx = 'y' . $yrs;
    $$ndx = rtrim($nms, ',');
}

// SHOW THE LOCAL STRINGS BY NAME
var_dump($y2009);
var_dump($y2010);
var_dump($y2011);

Open in new window

0
 
ZadoAuthor Commented:
Awesome, Roads_Roads script works perfectly! Ray, thanks for your help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.