469,636 Members | 1,680 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,636 developers. It's quick & easy.

Sorting an Array - CSORT

Nel
Hi all,

I am using php and mysql to search through a database of stores for the
nearest store to a given postcode.

I have managed to limit the selection to the nearest stores (roughly within
a given area), but once I have the array from mysql I need to do a
calculation to find the number of miles in between the store and the user's
postcode ($distance). I can do this by looping through the array.

Finally I need to sort the array by $distance, ASC. This is where I am
failing. I have read the FM and Googled. The best result is the one below
which seemed to do what I needed in terms of the search, but it gives an
error on the line

foreach($array as $row) {

Not sure why?

I am using PHP Version 4.3.8 on Windoze.

Nel.

_______________________________________________
POST FROM 2004 comp.lang.php
_______________________________________________

You can use array_multisort() to create a kind of column sort function:

function csort($array, $column) {
$s = array();
foreach($array as $row) {
$s[] = $row[$column];
}
array_multisort($s, SORT_ASC, $array);
return $array;

}
Example:

$foo = array(
array('firstname' => 'foo', 'lastname' => 'bar'),
array('firstname' => 'bar', 'lastname' => 'foo')
);

print_r(csort($foo, 'firstname'));

Output:

Array
(
[0] => Array
(
[firstname] => bar
[lastname] => foo
)

[1] => Array
(
[firstname] => foo
[lastname] => bar
)

)

HTH
Micha
Nov 28 '05 #1
5 1967
Nel wrote:
error on the line

foreach($array as $row) {

Not sure why?


From the FM at http://php.net/foreach : "foreach works only on arrays, and
will issue an error when you try to use it on a variable with a different
data type or an uninitialized variable."

--
E. Dronkert
Nov 28 '05 #2
Nel
"Ewoud Dronkert" <fi*******@lastname.net.invalid> wrote in message
news:42********************************@4ax.com...
Nel wrote:
error on the line

foreach($array as $row) {

Not sure why?


From the FM at http://php.net/foreach : "foreach works only on arrays, and
will issue an error when you try to use it on a variable with a different
data type or an uninitialized variable."

--
E. Dronkert


Thanks - I have the routine working but it doesn't do what I need.

I am trying to sort a multi-dimentional(?) array returned from mysql (i.e.
rows of data) based upon a calculation.
get result from mysql

sort through and calculate $distance($id) for each store, then sort the
result according to distance ASC.

list stores in order.
Nov 28 '05 #3
Nel wrote:
"Ewoud Dronkert" <fi*******@lastname.net.invalid> wrote in message
news:42********************************@4ax.com...
Nel wrote:
error on the line

foreach($array as $row) {

Not sure why?


From the FM at http://php.net/foreach : "foreach works only on arrays, and
will issue an error when you try to use it on a variable with a different
data type or an uninitialized variable."

--
E. Dronkert

Thanks - I have the routine working but it doesn't do what I need.

I am trying to sort a multi-dimentional(?) array returned from mysql (i.e.
rows of data) based upon a calculation.
get result from mysql

sort through and calculate $distance($id) for each store, then sort the
result according to distance ASC.

list stores in order.


Can you post the all code you're having trouble with, instead of just a
couple of lines?

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Nov 29 '05 #4
Nel
> Can you post the all code you're having trouble with, instead of just a
couple of lines?

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================


Here is the code I am using - I have managed to get the code to re-create
two temp arrays and output the distance and userid in distance order, but
this seems very messy and longwinded.

See below

<?php

mysql_select_db($database_exampleDB, $exampleDB);
$query_numUsers = sprintf("SELECT dest.outcode, dest.x, dest.y, u.* FROM
postcodes AS source, postcodes AS dest, hotels AS u WHERE
source.outcode ='%s' AND ((dest.x <= (source.x + %s) AND dest.x >=
(source.x -
%s)) AND (dest.y <= (source.y + %s) AND dest.y >= (source.y - %s))) AND
u.outcode = dest.outcode AND u.fullname != '%s' ORDER BY dest.outcode ASC",
$colname_numUsers,$r_numUsers,$r_numUsers,$r_numUs ers,$r_numUsers,$user_numUsers);
$numUsers = mysql_query($query_numUsers, $exampleDB) or die(mysql_error());

$row_numUsers = mysql_fetch_assoc($numUsers);
$totalRows_numUsers = mysql_num_rows($numUsers);

$sql = "SELECT * FROM postcodes WHERE outcode = '$Soutcode'";
$sqlresult = mysql_query($sql,$exampleDB) or die(mysql_errno());
$r = mysql_fetch_array($sqlresult);
$num_rows = mysql_num_rows($sqlresult);

$locX = $r[x];
$locY = $r[y];

echo "$totalRows_numUsers<p>";

if ($totalRows_numUsers > 0) { $temp = mysql_data_seek($numUsers, 0); }
$temp = 0;
while ($row_numUsers = mysql_fetch_assoc($numUsers)) {
$temp++;
$lid = $row_numUsers[id];
$netX = ($row_numUsers[x] - $locX);
$netY = ($row_numUsers[y] - $locY);
$hypotm = sqrt(($netX * $netX) + ($netY * $netY));
$hypotm = $hypotm / 1000 * 0.62 * 1.3;
$hypotm = number_format($hypotm,1);
$distance[$lid] = $hypotm;
$clist[$temp] = $lid;
}

if ($totalRows_numUsers > 0) { $temp = mysql_data_seek($numUsers, 0); }
$row_numUsers = mysql_fetch_assoc($numUsers);

array_multisort($distance, SORT_ASC, $clist);

$temp = 0;
foreach($distance as $dvalue) {

echo $dvalue." - ".$clist[$temp]."<br>";

$temp++;
}
?>

Outputs:

6

2.1 - 6 (distance - userid)
2.1 - 106
55.2 - 71
55.9 - 26
57.1 - 85
58.9 - 24

Nov 29 '05 #5
Nel wrote:
Can you post the all code you're having trouble with, instead of just a
couple of lines?

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================

Here is the code I am using - I have managed to get the code to re-create
two temp arrays and output the distance and userid in distance order, but
this seems very messy and longwinded.

See below

<?php

mysql_select_db($database_exampleDB, $exampleDB);
$query_numUsers = sprintf("SELECT dest.outcode, dest.x, dest.y, u.* FROM
postcodes AS source, postcodes AS dest, hotels AS u WHERE
source.outcode ='%s' AND ((dest.x <= (source.x + %s) AND dest.x >=
(source.x -
%s)) AND (dest.y <= (source.y + %s) AND dest.y >= (source.y - %s))) AND
u.outcode = dest.outcode AND u.fullname != '%s' ORDER BY dest.outcode ASC",
$colname_numUsers,$r_numUsers,$r_numUsers,$r_numUs ers,$r_numUsers,$user_numUsers);
$numUsers = mysql_query($query_numUsers, $exampleDB) or die(mysql_error());

$row_numUsers = mysql_fetch_assoc($numUsers);
$totalRows_numUsers = mysql_num_rows($numUsers);

$sql = "SELECT * FROM postcodes WHERE outcode = '$Soutcode'";
$sqlresult = mysql_query($sql,$exampleDB) or die(mysql_errno());
$r = mysql_fetch_array($sqlresult);
$num_rows = mysql_num_rows($sqlresult);

$locX = $r[x];
$locY = $r[y];

echo "$totalRows_numUsers<p>";

if ($totalRows_numUsers > 0) { $temp = mysql_data_seek($numUsers, 0); }
$temp = 0;
while ($row_numUsers = mysql_fetch_assoc($numUsers)) {
$temp++;
$lid = $row_numUsers[id];
$netX = ($row_numUsers[x] - $locX);
$netY = ($row_numUsers[y] - $locY);
$hypotm = sqrt(($netX * $netX) + ($netY * $netY));
$hypotm = $hypotm / 1000 * 0.62 * 1.3;
$hypotm = number_format($hypotm,1);
$distance[$lid] = $hypotm;
$clist[$temp] = $lid;
}

if ($totalRows_numUsers > 0) { $temp = mysql_data_seek($numUsers, 0); }
$row_numUsers = mysql_fetch_assoc($numUsers);

array_multisort($distance, SORT_ASC, $clist);

$temp = 0;
foreach($distance as $dvalue) {

echo $dvalue." - ".$clist[$temp]."<br>";

$temp++;
}
?>

Outputs:

6

2.1 - 6 (distance - userid)
2.1 - 106
55.2 - 71
55.9 - 26
57.1 - 85
58.9 - 24

Yep, quite convoluted.

As a suggestion - just read everything into an array, compute your
distance for each one and then sort. For instance (code not even syntax
checked, but you get the idea)...

function comp ($a, $b) {
return $b['dist'] - $a['dist']; // Reverse to sort descending
}

$sql = "SELECT * FROM postcodes WHERE outcode = '$Soutcode'";
$sqlresult = mysql_query($sql,$exampleDB);
if ($sqlresult) // or die() is SO user unfriendly!
$r = mysql_fetch_array($sqlresult);

(your big query here)
$numUsers = mysql_query($query_numUsers, $exampleDB);
if ($numUsers) { // or die is SO user unfriendly!
$i = 0;
while ($row_numUsers = mysql_fetch_array($numUsers) {
$all_numUsers [$i] = $row_numUsers;
$netX = ($row_numUsers[x] - $locX);
$netY = ($row_numUsers[y] - $locY);
$all_numUsers[$i++]['dist'] =
(sqrt(($netX * $netX) + ($netY * $netY))) / 1000 * 0.62 * 1.3
}
usort ($all_numUsers, 'cmp');
// Rest of your work
}
else ( // numUsers query failed
// Output an error message here
}
}
else { // Postcode query failed
// Output another error message here
}
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Nov 29 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Paul Kirby | last post: by
4 posts views Thread by LRW | last post: by
7 posts views Thread by Federico G. Babelis | last post: by
3 posts views Thread by SilverWolf | last post: by
7 posts views Thread by Kamal | last post: by
5 posts views Thread by lemlimlee | last post: by
5 posts views Thread by jrod11 | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.