Sort an array by 'price' value - php

I have an array in the following format - I want to be able to sort this so the highest price is first - i've tried array_multisort() but I'm not having any luck so far.
$working[33] = array('id' => '33', 'price' => '250.00');
$working[34] = array('id' => '34', 'price' => '277.88');
Using some function to sort by price the end product should look as follows:- as the 277 price is greater than 250
$working[34] = array('id' => '34', 'price' => '277.88');
$working[33] = array('id' => '33', 'price' => '250.00');

Sorting using usort :
usort($working, function($a, $b) {
return $a['price'] < $b['price'] ? 1 : -1;
});

use below function to get your problem resolve
function multisort (&$array, $key) {
$valsort=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$valsort[$ii]=$va[$key];
}
asort($valsort);
foreach ($valsort as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
multisort($multiarr,"order");

You can do it with array_multisort
Examples on the documentation.

Remove quotes OR use numeric sort.
String "24" is greater than "1834" because 2 is greater than 1.
My solution
$working[33] = array('id' => '33', 'price' => '250.00');
$working[34] = array('id' => '34', 'price' => '277.88');
$working[35] = array('id' => '35', 'price' => '1289.57');
$working[36] = array('id' => '36', 'price' => '15.42');
foreach ($working as $key => $row) {
$price[$key] = $row['price'];
}
array_multisort($price, SORT_NUMERIC, $working);
var_dump($working);
Output
array(4) {
[0]=>
array(2) {
["id"]=>
string(2) "36"
["price"]=>
string(5) "15.42"
}
[1]=>
array(2) {
["id"]=>
string(2) "33"
["price"]=>
string(6) "250.00"
}
[2]=>
array(2) {
["id"]=>
string(2) "34"
["price"]=>
string(6) "277.88"
}
[3]=>
array(2) {
["id"]=>
string(2) "35"
["price"]=>
string(7) "1289.57"
}
}

See Sorting arrays in php to solve your problem

usort($working, function ($a, $b) {
return bccomp($a['price'], $b['price'], 2);
});

Related

Multi-dimentional array how to get the nested value without foreach loop

I got output from one of the WordPress table cells. The following value is displayed.
$allcoinkey=get_option('_transient_mcw-custom-data');
var_dump($allcoinkey);
and the output:
[0]=>
array(2) {
["slug"]=>
string(7) "bitcoin"
["keywords"]=>
string(30) "بیتکوین,بیت کوین"
}
[1]=>
array(2) {
["slug"]=>
string(8) "ethereum"
["keywords"]=>
string(27) "اتریوم,اتاریوم"
}
}
How do I access keyword values where slug=bitcoin without foreach?
i use this sample code:
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
?>
You can do it like this:
<?php
$allcoinkey = [
[
'slug' => 'bitcoin',
'keywords' => 'بیتکوین,بیت کوین',
],
[
'slug' => 'ethereum',
'keywords' => 'اتریوم,اتاریوم',
],
];
$bitcoinKeywords = current(array_filter($allcoinkey, static function (array $cryptoCurrency) {
return $cryptoCurrency['slug'] === 'bitcoin';
}))['keywords'];
echo $bitcoinKeywords;

array_combine results only one result [duplicate]

This question already has answers here:
array_combine is return only last value
(2 answers)
Closed 3 years ago.
I am using the following code to get two arrays into one json result. But getting only the first index as result. Is there any error in the code or anybody can suggest an alternate method to get the same result.
$array1 = $_POST['array1'];
$array2 = $_POST['array2'];
$jsonArray = array();
foreach (array_combine( $array1, $array2 ) as $name => $value) {
$jsonArray[] = array('name' => $name, 'value' => $value);
}
echo $json = json_encode($jsonArray);
$_POST['array1'] = array(4) {
[0]=>
string(3) "day1"
[1]=>
string(3) "day2"
[2]=>
string(3) "day3"
[3]=>
string(3) "day4"
}
$_POST['array2'] = array(4) {
[0]=>
string(3) "item1"
[1]=>
string(3) "item2"
[2]=>
string(3) "item3"
[3]=>
string(3) "item4"
}
Expected result should be like
[{"name":"day1","value":"item1"},{"name":"day2","value":"item2"},{"name":"day3","value":"item3"}]
Try this,
$arr1 = array('0' => 'day1', '1' => 'day2', '2' => 'day3', '3' => 'day4');
echo'<pre>';print_r($arr1);
$arr2 = array('0' => 'item1','1' => 'item2','2' => 'item3','3' => 'item4');
echo'<pre>';print_r($arr2);
echo'<pre>';print_r(array_combine($arr1, $arr2));
$newArray = array();
foreach(array_combine($arr1, $arr2) as $key => $value){
array_push($newArray, array('name'=> $key,'value'=>$value));
}
echo'<pre>';print_r($newArray);
echo json_encode($newArray);die;

Sorting a Multi-Dimensional Array by sum of object values in PHP

I have the below multi dimensional array of products. Each array is a pair of products that make a product set, I need to order the multi dimensional array by the total price of each product set.
array(4) {
[0]=>
array(2) {
["product1"]=>
object(stdClass)#5075 (2) {
["product_id"]=>
string(4) "9416"
["price"]=>
string(6) "110.00"
}
["product2"]=>
object(stdClass)#5077 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "100.00"
}
}
[1]=>
array(2) {
["product1"]=>
object(stdClass)#5065 (2) {
["product_id"]=>
string(4) "1254"
["price"]=>
string(6) "75.00"
}
["product2"]=>
object(stdClass)#5067 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "62.00"
}
}
[2]=>
array(2) {
["product1"]=>
object(stdClass)#5055 (2) {
["product_id"]=>
string(4) "9416"
["price"]=>
string(6) "45.00"
}
["product2"]=>
object(stdClass)#5057 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "50.00"
}
}
[3]=>
array(2) {
["product1"]=>
object(stdClass)#5045 (2) {
["product_id"]=>
string(4) "9416"
["price"]=>
string(6) "60.00"
}
["product2"]=>
object(stdClass)#5047 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "25.00"
}
}
}
I need to sort the multi-dimensional array by the total sum of product1 + product2 in each array in ascending order. For example [1] should be above [0] as 75+62 is less than 110 +100.
If anyone can help me with this it would be greatly appreciated.
You can use usort() for this purpose:-
function comparePrice($a,$b)
{
$a_price = $a['product1']->price + $a['product2']->price;
$b_price = $b['product1']->price + $b['product2']->price;
if ($a_price ==$b_price) return 0;
return ($a_price<$b_price)? -1:1;
}
usort($array,'comparePrice');
A hardcoded working example:- https://3v4l.org/mTfu6
You need to use user-defined sorting
http://php.net/manual/en/function.usort.php
usort($products, function($a, $b) {
$prodA = $a['product1']['price'] + $a['product2']['price'];
$prodB = $b['product1']['price'] + $b['product2']['price'];
if($prodA == $prodB) return 0;
return ($prodA < $prodB) ? -1 : 1;
});
The php7+ "spaceship operator" (aka three-way-comparison operator) makes the syntax with usort() as clean and brief as possible.
Code: (Demo)
$array = [
[
"product1" => (object) ["product_id" => "9416", "price"=>"110.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"100.00"]
],
[
"product1" => (object) ["product_id" => "1254", "price"=>"75.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"62.00"]
],
[
"product1" => (object) ["product_id" => "9416", "price"=>"45.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"50.00"]
],
[
"product1" => (object) ["product_id" => "9416", "price"=>"60.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"25.00"]
]
];
usort($array, function($a, $b) {
return $a['product1']->price + $a['product2']->price <=> $b['product1']->price + $b['product2']->price;
});
var_export($array);
Output:
array (
0 => // sum = 85.00
array (
'product1' =>
(object) array(
'product_id' => '9416',
'price' => '60.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '25.00',
),
),
1 => // sum = 95.00
array (
'product1' =>
(object) array(
'product_id' => '9416',
'price' => '45.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '50.00',
),
),
2 => // sum = 137.00
array (
'product1' =>
(object) array(
'product_id' => '1254',
'price' => '75.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '62.00',
),
),
3 => // sum = 210.00
array (
'product1' =>
(object) array(
'product_id' => '9416',
'price' => '110.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '100.00',
),
),
)

Sort Multidimensional Array By Searched Word

I need to sort a multidimensional array by a searched keyword.
My array is like below.
<?php
array(
array(
'name' => '11th-Physics',
'branch' => 'Plus One',
'college' => 'Plus One',
),
array(
'name' => 'JEE-IIT',
'branch' => 'Physics',
'college' => 'IIT College',
),
array(
'name' => 'Physics',
'branch' => 'Bsc Physics',
'college' => 'College of Chemistry',
),
array(
'name' => 'Chemical Engineering',
'branch' => 'Civil',
'college' => 'Physics Training Center',
),
array(
'name' => 'Physics Education',
'branch' => 'Mechanical',
'college' => 'TBR',
),
)
?>
I need to sort this array when search keyword is physics . And after Sorting i need the result like below.
NEEDED RESULT
<?php
array(
array(
'name' => 'Physics',
'branch' => 'Bsc Physics',
'college' => 'College of Chemistry',
),
array(
'name' => 'Physics Education',
'branch' => 'Mechanical',
'college' => 'TBR',
),
array(
'name' => '11th-Physics',
'branch' => 'Plus One',
'college' => 'Plus One',
),
array(
'name' => 'JEE-IIT',
'branch' => 'Physics',
'college' => 'IIT College',
),
array(
'name' => 'Chemical Engineering',
'branch' => 'Civil',
'college' => 'Physics Training Center',
),
)
?>
That is I need to sort the array first by the name which is exactly like the searched keyword. Then wildcard search in name. Then to the next key branch and same as above. Is there any php function to sort this array like my requirement. I have already checked asort, usort. But I didn't get result properly.
Just call this simple function I just created for your requirement, It works just fine :) change the priority order according to your need
function sortArray($array,$itemToSearch)
{
$sortedArray = array();
$priorityOrder = ['name','branch','college'];
foreach ($priorityOrder as $key)
{
foreach ($array as $i => $value)
{
if(strpos(strtolower($value[$key]), strtolower($itemToSearch)) === 0)
{
array_push($sortedArray, $value);
unset($array[$i]);
}
}
foreach ($array as $i => $value)
{
if(strpos(strtolower($value[$key]), strtolower($itemToSearch)) > 0)
{
array_push($sortedArray, $value);
unset($array[$i]);
}
}
}
return $sortedArray;
}
Here we go
So I started from the algorithm in this answer and modified it to fit your requirements. Since you have three different "priorities" to you sorting, we have to use some temporary variables to separate the elements we wish sorted.
// arrays used to separate each row based on the row where the word "Physics" is found
$searchName = array();
$searchBranch = array();
$searchCollege = array();
// arrays used later for array_multisort
$foundInName = array();
$foundInBranch = array();
$foundInCollege = array();
foreach ($var as $key => $row) {
if(strpos(strtolower($row['name']), 'physics') !== false) {
$searchName[$key] = $row['name'];
$foundInName[] = $row;
}
elseif(strpos(strtolower($row['branch']), 'physics') !== false) {
$searchBranch[$key] = $row['branch'];
$foundInBranch[] = $row;
}
elseif(strpos(strtolower($row['college']), 'physics') !== false) {
$searchCollege[$key] = $row['college'];
$foundInCollege[] = $row;
}
}
// Note: I use SORT_NATURAL here so that "11-XXXXX" comes after "2-XXXXX"
array_multisort($searchName, SORT_NATURAL, $foundInName); // sort the three arrays separately
array_multisort($searchBranch, SORT_NATURAL, $foundInBranch);
array_multisort($searchCollege, SORT_NATURAL, $foundInCollege);
$sortedArray = array_merge($foundInName, $foundInBranch, $foundInCollege);
Outputting $sortedArray using var_dump() gives something like:
array(5) {
[0]=> array(3) {
["name"]=> string(12) "11th-Physics"
["branch"]=> string(8) "Plus One"
["college"]=> string(8) "Plus One"
}
[1]=> array(3) {
["name"]=> string(7) "Physics"
["branch"]=> string(11) "Bsc Physics"
["college"]=> string(20) "College of Chemistry"
}
[2]=> array(3) {
["name"]=> string(17) "Physics Education"
["branch"]=> string(10) "Mechanical"
["college"]=> string(3) "TBR"
}
[3]=> array(3) {
["name"]=> string(7) "JEE-IIT"
["branch"]=> string(7) "Physics"
["college"]=> string(11) "IIT College"
}
[4]=> array(3) {
["name"]=> string(20) "Chemical Engineering"
["branch"]=> string(5) "Civil"
["college"]=> string(23) "Physics Training Center"
}
}
As you can see 11th-Physics comes out first. That is because the ASCII value of numbers is lower than that of letters. To fix this, modify the $search... arrays by prepending a high ASCII character before the string.
if(strpos(strtolower($row['name']), 'physics') !== false) {
// if the first character is a number, prepend an underscore
$searchName[$key] = is_numeric(substr($row['name'], 0, 1)) ? '_'.$row['name'] : $row['name'];
$foundInName[] = $row;
}
Which yields the following output:
array(5) {
[0]=> array(3) {
["name"]=> string(7) "Physics"
["branch"]=> string(11) "Bsc Physics"
["college"]=> string(20) "College of Chemistry"
}
[1]=> array(3) {
["name"]=> string(17) "Physics Education"
["branch"]=> string(10) "Mechanical"
["college"]=> string(3) "TBR"
}
[2]=> array(3) {
["name"]=> string(12) "11th-Physics"
["branch"]=> string(8) "Plus One"
["college"]=> string(8) "Plus One"
}
[3]=> array(3) {
["name"]=> string(7) "JEE-IIT"
["branch"]=> string(7) "Physics"
["college"]=> string(11) "IIT College"
}
[4]=> array(3) {
["name"]=> string(20) "Chemical Engineering"
["branch"]=> string(5) "Civil"
["college"]=> string(23) "Physics Training Center"
}
}
Try it here!

what happens with my array? items disappear

what happens with my result array here? i expected the size of the result array to be equal to the input array, but its missing 3 entries.. where did they go? they didn't go to $ret , as they were supposed to..
code:
<?php
init();
$list_xy = array(
0 => array(
'id' => '308',
'x' => '37',
'y' => '63'
),
1 => array(
'id' => '963',
'x' => '38',
'y' => '134'
),
2 => array(
'id' => '385',
'x' => '39',
'y' => '132'
),
3 => array(
'id' => '1231',
'x' => '50',
'y' => '199'
),
4 => array(
'id' => '788',
'x' => '51',
'y' => '59'
),
5 => array(
'id' => '1151',
'x' => '53',
'y' => '61'
),
6 => array(
'id' => '671',
'x' => '55',
'y' => '60'
),
7 => array(
'id' => '1487',
'x' => '55',
'y' => '55'
)
);
$sorted_list_xy = sort_by_xy_distance($list_xy);
$sorted_list_xy_size = count($sorted_list_xy, COUNT_NORMAL);
$list_xy_size = count($list_xy, COUNT_NORMAL);
var_dump($sorted_list_xy_size == $list_xy_size ? "looks right" : "something is wrong", $sorted_list_xy_size, $list_xy_size);
die("died");
function sort_by_xy_distance($input_list)
{
$ret = array();
$a = $input_list[0];
array_push($ret, $input_list[0]);
$input_list[0] = null;
$i = 1;
for ($i = 1; $i < count($input_list); ++$i) {
if ($input_list[$i] == null) {
echo 'already added to list..';
continue;
}
$ii = 1;
$tmpdistance = 0;
$nearest = array(
'index' => -1,
'distance' => PHP_INT_MAX
);
for ($ii = 1; $ii < count($input_list); ++$ii) {
if ($input_list[$ii] == null || $ii == $i) {
//echo 'already added to list..';
continue;
}
$tmpdistance = abs($input_list[$ii]['x'] - $a['x']) + abs($input_list[$ii]['y'] - $a['y']);
if ($tmpdistance < $nearest['distance']) {
$nearest['index'] = $ii;
$nearest['distance'] = $tmpdistance;
}
}
assert($nearest['index'] != -1);
array_push($ret, $input_list[$nearest['index']]);
$a = $input_list[$nearest['index']];
$input_list[$nearest['index']] = null;
}
return $ret;
}
function init()
{
error_reporting(E_ALL);
set_error_handler("exception_error_handler");
}
function exception_error_handler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
output:
already added to list..already added to list..already added to
list..string(18) "something is wrong" int(5) int(8) died
expected output: (something similar to)
already added to list..already added to list..already added to
list..string(11) "looks right" int(8) int(8) died
what i expected the list to turn in to:
a list where the difference to the next's [x][y] is as little as possible, which would be:
array(8) {
[0]=>
array(3) {
["id"]=>
string(3) "308"
["x"]=>
string(2) "37"
["y"]=>
string(2) "63"
}
[1]=>
array(3) {
["id"]=>
string(3) "788"
["x"]=>
string(2) "51"
["y"]=>
string(2) "59"
}
[2]=>
array(3) {
["id"]=>
string(4) "1151"
["x"]=>
string(2) "53"
["y"]=>
string(2) "61"
}
[3]=>
array(3) {
["id"]=>
string(3) "671"
["x"]=>
string(2) "55"
["y"]=>
string(2) "60"
}
[4]=>
array(3) {
["id"]=>
string(4) "1487"
["x"]=>
string(2) "55"
["y"]=>
string(2) "55"
}
[5]=>
array(3) {
["id"]=>
string(3) "385"
["x"]=>
string(2) "39"
["y"]=>
string(3) "132"
}
[6]=>
array(3) {
["id"]=>
string(3) "963"
["x"]=>
string(2) "38"
["y"]=>
string(3) "134"
}
[7]=>
array(3) {
["id"]=>
string(4) "1231"
["x"]=>
string(2) "50"
["y"]=>
string(3) "199"
}
}
I suck at making graphical illustrations, but ill give it a go.
This is my map:
map http://imagizer.imageshack.us/a/img633/3521/E0HGRe.png
i need to visit all the black dots.
This is my current path:
this path is not very optimal..
here is the path i want:
and that's what the sort function is trying to find, the shortest path to visit all the black dots.
Distance calculation you should use Pythagoras' theorem (or just hypot, like #prodigitalson mentioned). For geo coordinates you could use this: http://www.movable-type.co.uk/scripts/latlong.html
Let's fix your code. Every step of your first loop should take one value from input value and place it into result. But it has continue inside, therefor some steps of first loop do not do their job. Try to remove first continue.
$list_xy = array(
0 => array(
'id' => '308',
'x' => '37',
'y' => '63'
),
1 => array(
'id' => '963',
'x' => '38',
'y' => '134'
),
2 => array(
'id' => '385',
'x' => '39',
'y' => '132'
),
3 => array(
'id' => '1231',
'x' => '50',
'y' => '199'
),
4 => array(
'id' => '788',
'x' => '51',
'y' => '59'
),
5 => array(
'id' => '1151',
'x' => '53',
'y' => '61'
),
6 => array(
'id' => '671',
'x' => '55',
'y' => '60'
),
7 => array(
'id' => '1487',
'x' => '55',
'y' => '55'
)
);
$sorted_list_xy = sort_by_xy_distance($list_xy);
$sorted_list_xy_size = count($sorted_list_xy, COUNT_NORMAL);
$list_xy_size = count($list_xy, COUNT_NORMAL);
var_dump($sorted_list_xy_size == $list_xy_size ? "looks right" : "something is wrong", $sorted_list_xy_size, $list_xy_size);
die("died");
function sort_by_xy_distance($input_list)
{
$ret = array();
$a = $input_list[0];
array_push($ret, $input_list[0]);
$input_list[0] = null;
$i = 1;
for ($i = 1; $i < count($input_list); ++$i) {
// up here
// if ($input_list[$i] == null) {
// echo 'already added to list..';
// continue;
// }
$ii = 1;
$tmpdistance = 0;
$nearest = array(
'index' => -1,
'distance' => PHP_INT_MAX
);
for ($ii = 1; $ii < count($input_list); ++$ii) {
if ($input_list[$ii] == null || $ii == $i) {
//echo 'already added to list..';
continue;
}
$tmpdistance = abs($input_list[$ii]['x'] - $a['x']) + abs($input_list[$ii]['y'] - $a['y']);
if ($tmpdistance < $nearest['distance']) {
$nearest['index'] = $ii;
$nearest['distance'] = $tmpdistance;
}
}
assert($nearest['index'] != -1);
array_push($ret, $input_list[$nearest['index']]);
$a = $input_list[$nearest['index']];
$input_list[$nearest['index']] = null;
}
return $ret;
}

Categories