Solved

Sorting elements from string

Posted on 2011-09-29
6
250 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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 108

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
This article discusses four methods for overlaying images in a container on a web page
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
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 …

896 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now