• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

[PHP] Order in array?

Status
Not open for further replies.
Joined
Dec 26, 2006
Messages
1,305
Reaction score
167
PHP:
$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0 ";
$string = explode(',', $string);
now, i want it make it order on
182|96|144|0,182|96|120|11081,182|96|96|111091
where 0 comes first, is this actually able to do?, becouse inserting in the database, ordening it via mysql etc is the only thing i could think of which would be a little bit much work.

thanks~
 
Custom Title Activated
Loyal Member
Joined
Jun 28, 2007
Messages
2,986
Reaction score
3
Right, this will work I think:

So you first split on the comma, then next you should make a new array containing the last number after the vertical line (so, split on the vertical line and take the last number) as the KEY, and the whole string (with the |'s) as it's VALUE. Now sort with http://nl.php.net/manual/en/function.ksort.php

Another way could be using callback functions: http://nl.php.net/manual/en/function.usort.php then in the compare function you retrieve just the last number and determine which is higher / lower.

I'd use the latter one I think, though I'm sure there's other ways to accomplish this.
 
Joined
Jun 8, 2007
Messages
1,985
Reaction score
490
Right, this will work I think:

So you first split on the comma, then next you should make a new array containing the last number after the vertical line (so, split on the vertical line and take the last number) as the KEY, and the whole string (with the |'s) as it's VALUE. Now sort with http://nl.php.net/manual/en/function.ksort.php

Another way could be using callback functions: http://nl.php.net/manual/en/function.usort.php then in the compare function you retrieve just the last number and determine which is higher / lower.

I'd use the latter one I think, though I'm sure there's other ways to accomplish this.
Why not just use the handy-dandy superfun_sort() function?
PHP:
function add_on($str,$x,$a)
{
	if(strlen($str)<$x)
	{
		$num = $x-strlen($str);
		
		$add_on = (string) null;
		for($k=0;$k<$num;$k++)
		{
			$add_on.=$a;
		}
		$str.=$add_on;
	}
	return $str;
}


function superfun_sort($str,$del_1,$del_2,$sort_columns = false)
{
	$return = (string) $str;
	
	$a1 = explode($del_1,$str);
	for($i=0;$i<count($a1);$i++)
	{
		$a1_5 = explode($del_2,$a1[$i]);
		$a2[$a1_5[3]] = $a1[$i];
		
		//echo '$a2['.$a1[$i].'] = '.$a1[$i].'<br />';
		
		$new_value = explode($del_2,$a1[$i]);
		asort($new_value);
		$key = $i;
		$old_value = (string) null;
		if($sort_columns) 
		{
			for($j=0;$j<count($new_value);$j++)
			{
				
				$key2 = (intval(substr($new_value[$j],0,2))<intval(substr($old_value,0,2))?$new_value[$j]:$old_value);
				$old_value = $new_value[$j];
			}
		}
		
		for($j=0;$j<count($new_value);$j++)
		{
			$new_value[$j] = add_on($new_value[$j],7,'x');
			$a3[$key2][$key][$j] = $new_value[$j];
			
			//echo '$a3['.$key2.']['.$key.']['.$j.'] = '.$a3[$key2][$key][$j].'<br />';
		}
		//echo '<hr />';
		$return = '';
	}
	$t = -1;
	$i = -1;
	foreach($a3 as $key=>$value)
	{
		
		$t++;
		
		foreach($a3[$key] as $k1 => $v1)
		{
			$i++;
			asort($a3[$key][$k1]);
			foreach($a3[$key][$k1] as $k => $v)
			{
				
				$v = str_replace('x','',$v);
				$a3[$key][$i][$k] = $v;
				//echo '$a3['.$key.']['.$i.']['.$k.'] = '.$v.'<br />';
				$return.=$v.$del_2;
				
			}
			
			$return=substr($return,0,strlen($return)-1).$del_1;
			//echo '<br />';
		}
		
	}
	return substr($return,0,strlen($return)-1);
}
PHP:
$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
$string = superfun_sort($string,',','|',true);
returns [if column sorting is true]:
0|144|182|***0|144|62|72,0|152|175|39,11081|120|182|***111091|182|96|96

returns [if column sorting is false]:
0|144|182|***11081|120|182|***111091|182|96|***0|144|62|72,0|152|175|39


That's as close as I can get, I had to do the add_on function so it recognized it as strings with all the same amount of characters in order to properly sort it the way you want. Before, it would put 96 before the other numbers.
 
Last edited:
Master Summoner
Joined
Jan 11, 2009
Messages
505
Reaction score
8
sp, try exploding the values with | then again assign the exploded strings to arrays then order it thereafter.

P.s. I miss this section and you all. :p
 
Master Summoner
Joined
Jan 11, 2009
Messages
505
Reaction score
8
you did, actually! You just needed to continue it. Take my suggested method! Let's see if it works out. :p
 
Joined
Dec 26, 2006
Messages
1,305
Reaction score
167
Why not just use the handy-dandy superfun_sort() function?
PHP:
function add_on($str,$x,$a)
{
    if(strlen($str)<$x)
    {
        $num = $x-strlen($str);
        
        $add_on = (string) null;
        for($k=0;$k<$num;$k++)
        {
            $add_on.=$a;
        }
        $str.=$add_on;
    }
    return $str;
}


function superfun_sort($str,$del_1,$del_2,$sort_columns = false)
{
    $return = (string) $str;
    
    $a1 = explode($del_1,$str);
    for($i=0;$i<count($a1);$i++)
    {
        $a1_5 = explode($del_2,$a1[$i]);
        $a2[$a1_5[3]] = $a1[$i];
        
        //echo '$a2['.$a1[$i].'] = '.$a1[$i].'<br />';
        
        $new_value = explode($del_2,$a1[$i]);
        asort($new_value);
        $key = $i;
        $old_value = (string) null;
        if($sort_columns) 
        {
            for($j=0;$j<count($new_value);$j++)
            {
                
                $key2 = (intval(substr($new_value[$j],0,2))<intval(substr($old_value,0,2))?$new_value[$j]:$old_value);
                $old_value = $new_value[$j];
            }
        }
        
        for($j=0;$j<count($new_value);$j++)
        {
            $new_value[$j] = add_on($new_value[$j],7,'x');
            $a3[$key2][$key][$j] = $new_value[$j];
            
            //echo '$a3['.$key2.']['.$key.']['.$j.'] = '.$a3[$key2][$key][$j].'<br />';
        }
        //echo '<hr />';
        $return = '';
    }
    $t = -1;
    $i = -1;
    foreach($a3 as $key=>$value)
    {
        
        $t++;
        
        foreach($a3[$key] as $k1 => $v1)
        {
            $i++;
            asort($a3[$key][$k1]);
            foreach($a3[$key][$k1] as $k => $v)
            {
                
                $v = str_replace('x','',$v);
                $a3[$key][$i][$k] = $v;
                //echo '$a3['.$key.']['.$i.']['.$k.'] = '.$v.'<br />';
                $return.=$v.$del_2;
                
            }
            
            $return=substr($return,0,strlen($return)-1).$del_1;
            //echo '<br />';
        }
        
    }
    return substr($return,0,strlen($return)-1);
}
PHP:
$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
$string = superfun_sort($string,',','|',true);
returns [if column sorting is true]:
0|144|182|***0|144|62|72,0|152|175|39,11081|120|182|***111091|182|96|96

returns [if column sorting is false]:
0|144|182|***11081|120|182|***111091|182|96|***0|144|62|72,0|152|175|39


That's as close as I can get, I had to do the add_on function so it recognized it as strings with all the same amount of characters in order to properly sort it the way you want. Before, it would put 96 before the other numbers.
Thats awesome, verry much thanks, But what i actually mean with the sort i want
if the string is
PHP:
182|96|144|0,
182|96|120|11081,
182|96|96|111091,
62|72|144|0,
39|175|152|0

Ordered:
PHP:
182|96|144|0,
62|72|144|0,
39|175|152|0,
182|96|120|11081,
182|96|96|111091
order on the last number after the | but beholding the same string

edit: how i do it now
PHP:
function order_citycontent($string){
	$globalstring = $string;
	$string = explode(',', $string);
	
	foreach ($string as &$value) {
		$total = $value;
		$value = explode('|', $value);
		mysql_query("INSERT INTO city_debug (id, city, total, var4) VALUES ('', '".mysql_real_escape_string($globalstring)."', '".mysql_real_escape_string($total)."', '".mysql_real_escape_string($value[3])."')");
	}
	
	$a = mysql_query("SELECT total FROM city_debug WHERE city = '".mysql_real_escape_string($globalstring)."' ORDER BY var4");
	$new = '';
	$i = 1;
	
	while($row = mysql_fetch_array($a)){
		$new .= $row['total'];
		if(mysql_num_rows($a) == $i){
			//donothing();
		}else{
			$new .= ',';
		}
		$i++;
	}

	mysql_query("DELETE FROM city_debug WHERE city = '".mysql_real_escape_string($globalstring)."'");
	return $new;
}
 
Last edited:
Joined
Jun 8, 2007
Messages
1,985
Reaction score
490
So is it done & working now then? or..

If not, I updated the function and added a new optional parameter: $sort_rows.

The default values should suit your needs, so it only needs 3 parameters.
PHP:
function add_on($str,$x,$a)
{
    if(strlen($str)<$x)
    {
        $num = $x-strlen($str);
        $add_on = (string) null;
        for($k=0;$k<$num;$k++)
        {
            $add_on.=$a;
        }
        $str.=$add_on;
    }
    return $str;
}


function superfun_sort($str,$del_1,$del_2,$sort_rows = false,$sort_columns = true)
{
    $return = (string) $str;
    $a1 = explode($del_1,$str);
    for($i=0;$i<count($a1);$i++)
    {
        $a1_5 = explode($del_2,$a1[$i]);
        $a2[$a1_5[3]] = $a1[$i];
        $new_value = explode($del_2,$a1[$i]);
        $key = $i;
        $old_value = (string) null;
        if($sort_columns) 
        {
            for($j=0;$j<count($new_value);$j++)
            {
                $key2 = (intval(substr($new_value[$j],0,2))<intval(substr($old_value,0,2))?$new_value[$j]:$old_value);
                $old_value = $new_value[$j];
            }
        }
		for($j=0;$j<count($new_value);$j++)
		{
			$new_value[$j] = add_on($new_value[$j],7,'x');
			$a3[$key2][$key][$j] = $new_value[$j];
		}
        $return = '';
    }
    $t = -1;
    $i = -1;
    foreach($a3 as $key=>$value)
    {
        $t++;
        foreach($a3[$key] as $k1 => $v1)
        {
            $i++;
			if($sort_rows)
			{
				asort($a3[$key][$k1]);
			}
            foreach($a3[$key][$k1] as $k => $v)
            {
                $v = str_replace('x','',$v);
                $a3[$key][$i][$k] = $v;
                //echo '$a3['.$key.']['.$i.']['.$k.'] = '.$v.'<br />';
                $return.=$v.$del_2;
            }
            
            $return=substr($return,0,strlen($return)-1).$del_1;
            //echo '<br />';
        }
    }
    return substr($return,0,strlen($return)-1);
}

PHP:
$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
echo str_replace(',','<br />',$string).'<hr />';
echo str_replace(',','<br />',superfun_sort($string,',','|'));

Code:
182|96|144|0
182|96|120|11081
182|96|96|111091
62|72|144|0
39|175|152|0
 = >
182|96|144|0
62|72|144|0
39|175|152|0
182|96|120|11081
182|96|96|111091

The funny thing now is, if you set both of them to false, it doesn't do anything. If you set both of them to true, it does far too much.. So I don't really know how practical it is to have all those gears spinning.. It could use some optimization ;)
 
Custom Title Activated
Loyal Member
Joined
Jun 28, 2007
Messages
2,986
Reaction score
3
Nice one.

This one is slightly shorter:
PHP:
function superfun_sort($string1, $string2)
{
    $value1 = substr(strrchr($string1, '|'), 1);
    $value2 = substr(strrchr($string2, '|'), 1);
    
    return ($value1 - $value2);
}

$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
$array = explode(',', $string);
usort($array, "superfun_sort");

Haven't tested it yet, don't have a localhost anymore. Also, can't 100% remember if PHP really doesn't care about types...(think it didn't).
 
Joined
Jun 8, 2007
Messages
1,985
Reaction score
490
Nice one.

This one is slightly shorter:
PHP:
function superfun_sort($string1, $string2)
{
    $value1 = substr(strrchr($string1, '|'), 1);
    $value2 = substr(strrchr($string2, '|'), 1);
    
    return ($value1 - $value2);
}

$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
$array = explode(',', $string);
usort($array, "superfun_sort");
Haven't tested it yet, don't have a localhost anymore. Also, can't 100% remember if PHP really doesn't care about types...(think it didn't).
Nope, it doesn't care..

Works with a subtle difference. It just swaps the repeating 0 rows for some reason.. Hmm.. I wish I knew what you know about sorting functions :blink: That would make life so much simpler.. and organized!
Code:
original:
182|96|144|0
182|96|120|11081
182|96|96|111091
62|72|144|0
39|175|152|0

superfun_sort [spn]
182|96|144|0
62|72|144|0
39|175|152|0
182|96|120|11081
182|96|96|111091

superfun_sort [daevius]
182|96|144|0
39|175|152|0
62|72|144|0
182|96|120|11081
182|96|96|111091
You just made me appear to have a mental illness for writing all that code :laugh:
Very good stuff mate, nice to see you contributing some code again :cool:
 
Custom Title Activated
Loyal Member
Joined
Aug 8, 2004
Messages
3,892
Reaction score
20
You just made me appear to have a mental illness for writing all that code :laugh:

To be frank, that is quite an apt observation. It took you over 40 lines of code to sort. Deavius used 9 lines, not counting empty ones. This solution does it in five, without the additional function declaration and without the relatively slow string comparisons:
PHP:
$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
$array  = explode(',', $string);
foreach ($array as $item)
  $order[] = array_pop(explode('|', $item));
array_multisort($order, $array);

I could do it in three, but that would become unreadable :laugh:
 
Joined
Jun 8, 2007
Messages
1,985
Reaction score
490
To be frank, that is quite an apt observation. It took you over 40 lines of code to sort. Deavius used 9 lines, not counting empty ones. This solution does it in five, without the additional function declaration and without the relatively slow string comparisons:
PHP:
$string = "182|96|144|0,182|96|120|11081,182|96|96|111091,62|72|144|0,39|175|152|0";
$array  = explode(',', $string);
foreach ($array as $item)
  $order[] = array_pop(explode('|', $item));
array_multisort($order, $array);
I could do it in three, but that would become unreadable :laugh:

You never seize to amaze me :thumbup1:
 
Status
Not open for further replies.
Back
Top