Solved

Sorting elements from string

Posted on 2011-09-29
6
252 Views
Last Modified: 2012-05-12
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.
0
Comment
Question by:Zado
  • 3
  • 2
6 Comments
 
LVL 27

Expert Comment

by:Lukasz Chmielewski
ID: 36813748
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
 
LVL 8

Author Comment

by:Zado
ID: 36813792
Ok, I will wait for final result, thanks for your help!
0
 
LVL 27

Expert Comment

by:Lukasz Chmielewski
ID: 36813828
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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 109

Assisted Solution

by:Ray Paseur
Ray Paseur earned 100 total points
ID: 36813840
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
 
LVL 27

Accepted Solution

by:
Lukasz Chmielewski earned 400 total points
ID: 36813841
<?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
 
LVL 8

Author Comment

by:Zado
ID: 36813966
Awesome, Roads_Roads script works perfectly! Ray, thanks for your help.
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses four methods for overlaying images in a container on a web page
There’s a good reason for why it’s called a homepage – it closely resembles that of a physical house and the only real difference is that it’s online. Your website’s homepage is where people come to visit you. It’s the family room of your website wh…
The viewer will get a basic understanding of what section 508 compliance can entail, learn about skip navigation links, alt text, transcripts, and font size controls.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question