Adding a variable to the end of a mysql query.
Now I need to be able to sort by the associated value. Can someone help? I have tried several different sorting methods.
$result2 = mysqli_query($datacon,
"SELECT * FROM spreadsheet
WHERE brand = '$brand'
AND package = '$package'
AND HIDE_FROM_SEARCH = '0'
GROUP BY ACCTNAME $pages->limit");
echo mysqli_error($datacon);
while($row = mysqli_fetch_array($result2)) {
$lat_B=$row['LATITUDE'];
$long_B=$row['LONGITUDE'];
$lat_A = round($lat_A,2);
$long_A = round($long_A,2);
$lat_B = round($lat_B,2);
$long_B = round($long_B,2);
$distance = new calcDist($lat_A, $long_A, $lat_B, $long_B);
$distance = $distance->calcDist($lat_A, $long_A, $lat_B, $long_B);
$distance = round($distance,2);
$locationSort=array($row);
$locationSort['distance']=$distance;
FOR EACH SOMETHING?
}
I have amended my previous post to reflect my usage of an answer.
$result2 = mysqli_query($datacon,"SELECT * FROM spreadsheet WHERE brand = '$brand'
AND package = '$package' and HIDE_FROM_SEARCH = '0' GROUP BY ACCTNAME $pages->limit");
echo(mysqli_error($datacon));
class sortBydistance
{
function sortBydistance($a, $b) {
if ($a['distance'] == $b['distance']) {
return 0;
}
return ($a['distance'] < $b['distance']) ? -1 : 1;
}
}
while($row = mysqli_fetch_array($result2))
{
$lat_B=$row['LATITUDE'];
$long_B=$row['LONGITUDE'];
$lat_A = round($lat_A,2);
$long_A = round($long_A,2);
$lat_B = round($lat_B,2);
$long_B = round($long_B,2);
$distance = new calcDist($lat_A, $long_A, $lat_B, $long_B);
$distance = $distance->calcDist($lat_A, $long_A, $lat_B, $long_B);
$distance = round($distance,2);
}
$locationSort=array($row);
$locationSort['distance']=$distance;
uasort($locationSort, array($this, "sortBydistance"));
print_r($locationSort);
Probably you are not retrieving correctly the $bran and $package variables..
$result2 = mysqli_query($datacon,
"SELECT * FROM spreadsheet
WHERE brand = '".$brand."'
AND package = '".$package."'
AND HIDE_FROM_SEARCH = '0'
GROUP BY ACCTNAME ".$pages->limit.");
First, create your array of entries, and store it in an array, we will call $rows.
You want to use the PHP function usort here to provide a custom sorting callback.
Let's say you have an array like the following:
$rows = array(
array("latitude" => 5, "distance" => 10),
array("latitude" => 10, "distance" => 5),
array("latitude" => 56, "distance" => 48)
);
You expect this array of $rows to be reordered so that the entry with latitude == 10 is first, latitude == 5 is second, and latitude == 56 is third, based on their distance.
usort($rows, function ($a, $b) {
$a = $a['distance'];
$b = $b['distance'];
return $a == $b ? 0 : $a > $b ? 1 : -1;
});
Output
Array
(
[0] => Array
(
[latitude] => 10
[distance] => 5
)
[1] => Array
(
[latitude] => 5
[distance] => 10
)
[2] => Array
(
[latitude] => 56
[distance] => 48
)
)
See this demonstration at ideone.com
Alternatively, you could try to find a SortedArray implementation that would keep the elements sorted as they were inserted to the array, rather than only when you call usort() on the array. That's a little too advanced for this question, though.
Try this after your while loop:
uasort($locationSort, 'sortBydistance');
// or uasort($locationSort, array($this, "sortBydistance")); if you are using withing a class
print_r($locationSort);
function sortBydistance($a, $b) {
if ($a['distance'] == $b['distance']) {
return 0;
}
return ($a['distance'] < $b['distance']) ? -1 : 1;
}
Related
I have a already defined array, containing values just like the one below:
$arr = ['a','b','c'];
How could one add the following using PHP?
$arr = [
'a' => 10,
'b' => 5,
'c' => 21
]
I have tried:
$arr['a'] = 10 but it throws the error: Undefined index: a
I am surely that I do a stupid mistake.. could someone open my eyes?
Full code below:
$finishes = []; //define array to hold finish types
foreach ($projectstages as $stage) {
if ($stage->finish_type) {
if(!in_array($stage->finish_type, $finishes)){
array_push($finishes, $stage->finish_type);
}
}
}
foreach ($projectunits as $unit) {
$data[$i] = [
'id' => $unit->id,
'project_name' => $unit->project_name,
'block_title' => $unit->block_title,
'unit' => $unit->unit,
'core' => $unit->core,
'floor' => $unit->floor,
'unit_type' => $unit->unit_type,
'tenure_type' => $unit->tenure_type,
'floors' => $unit->unit_floors,
'weelchair' => $unit->weelchair,
'dual_aspect' => $unit->dual_aspect
];
$st = array();
$bs = '';
foreach ($projectstages as $stage) {
$projectmeasure = ProjectMeasure::select('measure')
->where('project_id',$this->projectId)
->where('build_stage_id', $stage->id)
->where('unit_id', $unit->id)
->where('block_id', $unit->block_id)
->where('build_stage_type_id', $stage->build_stage_type_id)
->first();
$st += [
'BST-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure : '0')
];
if (($stage->is_square_meter == 0) && ($stage->is_draft == 0)) {
$height = ($stage->height_override == 0 ? $unit->gross_floor_height : $stage->height_override); //08.14.20: override default height if build stage type has it's own custom height
$st += [
'BST-sqm-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure * $height: '0')
];
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure * $height: '0') * ($stage->both_side ? 2 : 1); //error is thrown at this line
}
} else {
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure : '0');
}
}
}
$data[$i] = array_merge($data[$i], $st);
$data[$i] = array_merge($data[$i], $finishes[$stage->finish_type]);
$i++;
}
The above code is used as is and the array $finishes is the one from the first example, called $arr
You're using += in your real code instead of =. That tries to do maths to add to an existing value, whereas = can just assign a new index with that value if it doesn't exist.
+= can't do maths to add a number to nothing. You need to check first if the index exists yet. If it doesn't exist, then assign it with an initial value. If it already exists with a value, then you can add the new value to the existing value.
If you want to convert the array of strings to a collection of keys (elements) and values (integers), you can try the following:
$arr = ['a','b','c'];
$newVals = [10, 5, 21];
function convertArr($arr, $newVals){
if(count($arr) == count($newVals)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$temp = $arr[$i];
$arr[$temp] = $newVals[$i];
unset($arr[$i]);
}
}
return $arr;
}
print_r(convertArr($arr, $newVals));
Output:
Array ( [a] => 10 [b] => 5 [c] => 21 )
Hello i want to pagination an array with for loop but the problem is my array keys is not like(1,2,3,4,5 ... etc) ,,
for ($x=0; $x<$members_per_page; $x++) {
$position = (int) ($currentPage-1) * $members_per_page + $x;
$member = get_userdata($members[$position]);
blackfyre_clan_members_links($member,$post_meta_arr, $post_id, $isleader);
if ( $position >= $last_key ) break;
}
and my array content is :
Array
(
[4] => Array
(
[boid] => 4
[cr_nickname] =>
)
[564] => Array
(
[boid] => 564
[cr_nickname] =>
)
) .... ETC
You could force your array to have sequential keys by using array_values like below:
for ($x=0; $x<$members_per_page; $x++) {
$position = (int) ($currentPage-1) * $members_per_page + $x;
$member = get_userdata(array_values($members)[$position]);
blackfyre_clan_members_links($member,$post_meta_arr, $post_id, $isleader);
if ( $position >= $last_key ) break;
}
However a (possibly) better way to paginate would be :
$offset = (int) ($currentPage-1) * $members_per_page;
$slice = array_slice ($members, $offset, $members_per_page,true);
array_walk($slice, function ($member) use ($post_meta, $post_id, $isleader) {
blackfyre_clan_members_links($member,$post_meta_arr, $post_id, $isleader);
});
Just use foreach ($members as $member){} instead of for
I want to sort a multidimensional array based on 'distance' value.If distance are equal then i have to compare 'created' date then price and finally alphabetical order.Who can i sort an array based on different key values.
$array = array( 0 => array('title'=>'title1', 'distance'=>200, 'date'=>'2014-16','price'=>12), 1 => array('title'=>'title2', 'distances'=>100, 'date'=>'014-03-15','price'=>17));
array look like this.First priority to distnce then date and so on
I wrote a function for this exact thing,
Checkout My Gist:
https://gist.github.com/chazmead/8829079
<?php
/**
* Sort a 2 dimension array with values in the second dimension
*
* Developer: chazmead89#gmail.com // #RaggaMuffin-4201
*
* Order can be string of a field, which will default to asc
* OR as array(field1,field2...fieldn) each defaulting to asc
* OR as assoc array(field1 => dir[asc|desc], field2 => dir[asc|desc]...fieldn
* => dir[asc|desc])
*
* PHP Sort constants can be used: SORT_ASC | SORT_DESC
*
* #param array $array array to sort - passed by reference
* #param mixed $order
* #return null
*/
function multisort(&$array,$order) {
usort($array, function($a,$b) use ($order) {
$sortMap = array('asc'=>SORT_ASC,'desc'=>SORT_DESC);
$aObj = (object)$a;
$bObj = (object)$b;
if (is_string($order))
$order = array($order);
if (is_object($order))
$order = (array)$order;
$i = 0;
$cOrder = count($order);
foreach($order as $field => $dir) {
if (is_numeric($field)) {
$field = $dir;
$dir = SORT_ASC;
}
// Goto next step when a mis-match is found.
if ($aObj->$field != $bObj->$field)
break;
// All fields match return 0
if (++$i === $cOrder)
return 0;
}
if(!is_numeric($dir)) {
$dir = strtolower($dir);
$dir = $sortMap[$dir];
}
$d = ($dir === SORT_DESC) ? -1 : 1;
$c = ($aObj->$field < $bObj->$field) ? -1 : 1;
return $c*$d;
});
}
This can be used like so:
$array = array( 0 => array('title'=>'title1', 'distance'=>200, 'date'=>'2014-03-16','price'=>12), 1 => array('title'=>'title2', 'distances'=>100, 'date'=>'014-03-15','price'=>17), );
$order = array('distance' => SORT_ASC, 'created' => SORT_ASC, 'title' => SORT_ASC);
multisort($array,$order);
I have the following Arrays:
$front = array("front_first","front_second");
$inside = array("inside_first", "inside_second", "inside_third");
$back = array("back_first", "back_second", "back_third","back_fourth");
what I need to do is combine it so that an output would look like this for the above situation. The output order is always to put them in order back, front, inside:
$final = array(
"back_first",
"front_first",
"inside_first",
"back_second",
"front_second",
"inside_second",
"back_third",
"front_second",
"inside_third",
"back_fourth",
"front_second",
"inside_third"
);
So basically it looks at the three arrays, and whichever array has less values it will reuse the last value multiple times until it loops through the remaining keys in the longer arrays.
Is there a way to do this?
$front = array("front_first","front_second");
$inside = array("inside_first", "inside_second", "inside_third");
$back = array("back_first", "back_second", "back_third","back_fourth");
function foo() {
$args = func_get_args();
$max = max(array_map('sizeof', $args)); // credits to hakre ;)
$result = array();
for ($i = 0; $i < $max; $i += 1) {
foreach ($args as $arg) {
$result[] = isset($arg[$i]) ? $arg[$i] : end($arg);
}
}
return $result;
}
$final = foo($back, $front, $inside);
print_r($final);
demo: http://codepad.viper-7.com/RFmGYW
Demo
http://codepad.viper-7.com/xpwGha
PHP
$front = array("front_first", "front_second");
$inside = array("inside_first", "inside_second", "inside_third");
$back = array("back_first", "back_second", "back_third", "back_fourth");
$combined = array_map("callback", $back, $front, $inside);
$lastf = "";
$lasti = "";
$lastb = "";
function callback($arrb, $arrf, $arri) {
global $lastf, $lasti, $lastb;
$lastf = isset($arrf) ? $arrf : $lastf;
$lasti = isset($arri) ? $arri : $lasti;
$lastb = isset($arrb) ? $arrb : $lastb;
return array($lastb, $lastf, $lasti);
}
$final = array();
foreach ($combined as $k => $v) {
$final = array_merge($final, $v);
}
print_r($final);
Output
Array
(
[0] => back_first
[1] => front_first
[2] => inside_first
[3] => back_second
[4] => front_second
[5] => inside_second
[6] => back_third
[7] => front_second
[8] => inside_third
[9] => back_fourth
[10] => front_second
[11] => inside_third
)
Spreading the column data from multiple arrays with array_map() is an easy/convenient way to tranpose data. It will pass a full array of elements from the input arrays and maintain value position by assigning null values where elements were missing.
Within the custom callback, declare a static cache of the previously transposed row. Iterate the new transposed row of data and replace any null values with the previous rows respective element.
After transposing the data, call array_merge(...$the_transposed_data) to flatten the results.
Code: (Demo)
$front = ["front_first", "front_second"];
$inside = ["inside_first", "inside_second", "inside_third"];
$back = ["back_first", "back_second", "back_third", "back_fourth"];
var_export(
array_merge(
...array_map(
function(...$cols) {
static $lastSet;
foreach ($cols as $i => &$v) {
$v ??= $lastSet[$i];
}
$lastSet = $cols;
return $cols;
},
$back,
$front,
$inside
)
)
);
Output:
array (
0 => 'back_first',
1 => 'front_first',
2 => 'inside_first',
3 => 'back_second',
4 => 'front_second',
5 => 'inside_second',
6 => 'back_third',
7 => 'front_second',
8 => 'inside_third',
9 => 'back_fourth',
10 => 'front_second',
11 => 'inside_third',
)
** EDIT ** What would happen if I only used arrays, e.g.
array(
array('name' => 'bla', 'distance' => '123');
array('name' => 'b123a', 'distance' => '1234214');
);
Would this be easier to find the min value ?
Hi there I'm trying to retrieve the object which has the lowest distance value from an array of objects. This is my data set below;
[0] => myObjectThing Object
(
[name:myObjectThing:private] => asadasd
[distance:myObjectThinge:private] => 0.9826368952306
)
[1] => myObjectThing Object
(
[name:myObjectThing:private] => 214gerwert24
[distance:myObjectThinge:private] => 1.5212312547306
)
[2] => myObjectThing Object
(
[name:myObjectThing:private] => abc123
[distance:myObjectThinge:private] => 0.0000368952306
)
So I'd like to be able to retieve the object which has the smallest distance value. In this case it would be object with name: abc123
Hmm for PHP >= 5.3 I would try something like this:
$Object = array_reduce($data,function($A,$B){
return $A->distance < $B->distance ? $A : $B;
})
For PHP < 5.3 the fillowing would suffice:
function user_defined_reduce($A,$B){
return $A->distance < $B->distance ? $A : $B;
}
$Object = array_reduce($data,"user_defined_reduce");
Previously suggested answers did not explain the need to include an $initial value to array_reduce(). The solution did not work because of it.
This one works for me (PHP 5.3.13):
$array = array(
array(
'name' => 'something',
'value' => 56
),
array(
'name' => 'else',
'value' => 54
),
array(
'name' => 'else',
'value' => 58
),
array(
'name' => 'else',
'value' => 78
)
);
$object = array_reduce($array, function($a, $b){
return $a['value'] < $b['value'] ? $a : $b;
}, array_shift($array));
print_r($object);
This will give me:
[0] => Array
(
[name] => else
[value] => 54
)
Whereas the previous solution gave me null. I'm assuming that PHP < 5.3 would require a similar initial value to be specified to array_reduce().
You can't flatten this as it isn't a plain old multi-dimensional array with just the values.
This should work:
$min = $object[0];
for ($i = 1; $i < count($object); $i++)
if ($object[$i]['distance'] < $min['distance'])
$min = $object[$i];
This example should give you a hint in the right direction:
<?php
$a = new stdClass();
$a->foo = 2;
$b = new stdClass();
$b->foo = 3;
$c = new stdClass();
$c->foo = 1;
$init = new stdClass();
$init->foo = 1000;
$vals = array( $a, $b, $c );
var_dump(
array_reduce(
$vals,
function ( $x, $y )
{
if ( $x->foo < $y->foo )
{
return $x;
}
else
{
return $y;
}
},
$init
)
);
?>
try:
$myObjectCollection = ...;
$minObject = $myObjectCollection[0]; // or reset($myObjectCollection) if you can't ensure numeric 0 index
array_walk($myObjectCollection, function($object) use ($minObject) {
$minObject = $object->distance < $minObject->distance ? $object : $minObject;
});
but from the looks of your dump. name and distance are private. So you want be able to access them from the object directly using ->. You'll need some kind of getter getDistance()
$objectsArray = array(...); // your objects
$distance = null;
$matchedObj = null;
foreach ( $objectsArray as $obj ) {
if ( is_null($distance) || ( $obj->distance < $distance ) ) {
$distance = $obj->distance;
$matchedObj = $obj;
}
}
var_dump($matchedObj);
AD EDIT:
If you will use arrays instead of objects, change $obj->distance to $obj['distance'].