I am trying to sort json object by same key and merge the value part using PHP but not getting the result as expected. My code is below:
$customArr=[{"attribute_code":"budget","value":"141"},{"attribute_code":"restaurants","value":"166"},{"attribute_code":"food_type","value":"172"},{"attribute_code":"budget","value":"142"},{"attribute_code":"restaurants","value":"168"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"143"},{"attribute_code":"restaurants","value":"170"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"162"},{"attribute_code":"restaurants","value":"171"},{"attribute_code":"food_type","value":"172"}]
function sortByName($a, $b){
$a = $a['attribute_code'];
$b = $b['attribute_code'];
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
usort($customArr, 'sortByName');
Here I need if attribute_code is same then push the respective value into one array and also the duplicate value should not be there. The expected result is given below.
[{"attribute_code":"budget","value":[141,142,143,162]},{}.....]
But in my case the expected result not coming.
Using array_reduce() you can try it. array_reduce() callback takes two arguments, who's first argument is the old/previous iteration value and second argument is the current iteration value/element.
So using this function we can holds our current iteration values to the previous iteration value (total values).
array_reduce() iteratively reduce the array to a single value using a callback function.
$customArr = json_decode('[{"attribute_code":"budget","value":"141"},{"attribute_code":"restaurants","value":"166"},{"attribute_code":"food_type","value":"172"},{"attribute_code":"budget","value":"142"},{"attribute_code":"restaurants","value":"168"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"143"},{"attribute_code":"restaurants","value":"170"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"162"},{"attribute_code":"restaurants","value":"171"},{"attribute_code":"food_type","value":"172"}]', true);
$data = array_reduce($customArr, function ($acc, $new) {
if (isset($acc[$new['attribute_code']])) {
$old_value = $acc[$new['attribute_code']]['value'];
$acc[$new['attribute_code']]['value'] = array_unique(is_array($old_value) ? array_merge($old_value, [$new['value']]) : [$old_value, $new['value']]);
} else {
$acc[$new['attribute_code']] = $new;
}
return $acc;
}, []);
ksort($data);
echo '<pre>', json_encode(array_values($data));
Working demo.
At the moment you are just sorting the entries according to the attribute_code and doing nothing about merging the data items.
This code creates a new output array (keyed it by the attribute_code), if the code is already there it adds the value into the list of existing values, if not it adds a new item in, creating the value as an array (with the first item in). Lastly it uses ksort() to sort the items.
If you don't need these keys, then array_values() will give you a plain array (as in the output)...
$json='[{"attribute_code":"budget","value":"141"},{"attribute_code":"restaurants","value":"166"},{"attribute_code":"food_type","value":"172"},{"attribute_code":"budget","value":"142"},{"attribute_code":"restaurants","value":"168"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"143"},{"attribute_code":"restaurants","value":"170"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"162"},{"attribute_code":"restaurants","value":"171"},{"attribute_code":"food_type","value":"172"}]';
$customArr = json_decode($json, true);
$output = [];
foreach ( $customArr as $attribute ) {
if ( isset ( $output[$attribute['attribute_code']])) {
$output[$attribute['attribute_code']]['value'][] = $attribute['value'];
}
else {
$output[$attribute['attribute_code']] = ["attribute_code"=>$attribute['attribute_code'],
"value"=> [$attribute['value']]];
}
}
// Make sure values are unique
foreach ( $output as $code => $value ){
$output[$code]['value'] = array_unique($output[$code]['value']);
}
ksort($output);
print_r(array_values($output));
gives...
Array
(
[0] => Array
(
[attribute_code] => budget
[value] => Array
(
[0] => 141
[1] => 142
[2] => 143
[3] => 162
)
)
[1] => Array
(
[attribute_code] => food_type
[value] => Array
(
[0] => 172
[1] => 173
)
)
[2] => Array
(
[attribute_code] => restaurants
[value] => Array
(
[0] => 166
[1] => 168
[2] => 170
[3] => 171
)
)
)
You have a JSON string, not an array.
$jsonString = '[{"attribute_code":"budget","value":"141"},{"attribute_code":"restaurants","value":"166"},{"attribute_code":"food_type","value":"172"},{"attribute_code":"budget","value":"142"},{"attribute_code":"restaurants","value":"168"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"143"},{"attribute_code":"restaurants","value":"170"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"162"},{"attribute_code":"restaurants","value":"171"},{"attribute_code":"food_type","value":"172"}]';
$customArr = json_decode($jsonString, true);
function sortByName($a, $b)
{
$a = $a['attribute_code'];
$b = $b['attribute_code'];
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
usort($customArr, 'sortByName');
The similar solution as above, but a little different using a temp variable and in a single iteration:
<?php
$str='[{"attribute_code":"budget","value":"141"},{"attribute_code":"restaurants","value":"166"},{"attribute_code":"food_type","value":"172"},{"attribute_code":"budget","value":"142"},{"attribute_code":"restaurants","value":"168"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"143"},{"attribute_code":"restaurants","value":"170"},{"attribute_code":"food_type","value":"173"},{"attribute_code":"budget","value":"162"},{"attribute_code":"restaurants","value":"171"},{"attribute_code":"food_type","value":"172"}]';
$arr = json_decode($str,true);
$temp = $result= [];
foreach($arr as $key=>$customer){
if(in_array($customer['attribute_code'], $temp)){
$index=array_search($customer['attribute_code'],$temp);
if(!in_array($customer['value'],$result[$index]['value'])){
$result[$index]['value'][]=$customer['value'];
}
}else {
$temp[]=$customer['attribute_code'];
$result[]=[
'attribute_code'=>$customer['attribute_code'],
'value'=>[$customer['value']]
];
}
}
unset($temp);
print_r($result);
echo json_encode($result);
?>
Result :
Array
(
[0] => Array
(
[attribute_code] => budget
[value] => Array
(
[0] => 141
[1] => 142
[2] => 143
[3] => 162
)
)
[1] => Array
(
[attribute_code] => restaurants
[value] => Array
(
[0] => 166
[1] => 168
[2] => 170
[3] => 171
)
)
[2] => Array
(
[attribute_code] => food_type
[value] => Array
(
[0] => 172
[1] => 173
)
)
)
JSON ENCODED RESPONSE
[{"attribute_code":"budget","value":["141","142","143","162"]},{"attribute_code":"restaurants","value":["166","168","170","171"]},{"attribute_code":"food_type","value":["172","173"]}]
I am trying to create a golf livescore leaderboard, but am having one issue. I would like to order the array by who has the lowest points, but also, if 2 or more have the same points, order those by which hole they are on.
My initial array looks like this:
Array
(
[0] => Array
(
[userid] => 1301
[holes] => 6
[points] => -2
)
[1] => Array
(
[userid] => 231
[holes] => 5
[points] => 7
)
[2] => Array
(
[userid] => 3421
[holes] => 6
[points] => 7
)
[3] => Array
(
[userid] => 46
[holes] => 6
[points] => 3
)
[4] => Array
(
[userid] => 745
[holes] => 4
[points] => 7
)
)
Now, then I do this to order the array by points:
$sortArray = array();
foreach($playersArray as $person){
foreach($person as $key=>$value){
if(!isset($sortArray[$key])){
$sortArray[$key] = array();
}
$sortArray[$key][] = $value;
}
}
$orderby = "points";
array_multisort($sortArray[$orderby],SORT_ASC,$playersArray);
This orders the array by points, but as you can see, I have 3 players with 7 points but on different holes and would like to order those with same holes so the highest rank is the one on the lowest hole.
Hope this makes sense and any help is appreciated.
Thanks in advance :-)
Use usort.
Example:
usort($playersArray, function ($a, $b) {
if ($a['points'] == $b['points']) {
return $a['holes'] < $b['holes'];
}
return $a['points'] < $b['points'];
});
Change < to > to change sorting order.
Use usort.
This function will sort an array by its values using a user-supplied comparison function. If the array you wish to sort needs to be sorted by some non-trivial criteria, you should use this function.
usort($score, function ($a, $b) {
return $a['points'] - $b['points']
? $a['points'] - $b['points']
: $a['holes'] - $b['holes'];
});
Try this way :
function order_by_points($a, $b){
if ($a['points'] == $b['points'])
// sort the higher points first:
return $a['points'] < $b['points'] ? 1 : -1;
}
i have created an arry like
$arr[0]['ref']=5;
$arr[0]['name']='name0';
$arr[1]['ref']=6;
$arr[1]['name']='name1';
$arr[2]['ref']=4;
$arr[2]['name']='name2';
$arr[3]['ref']='';
$arr[3]['name']='name3';
$arr[4]['ref']='9';
$arr[4]['name']='name4';
$arr[5]['ref']=''
$arr[5]['name']='name5'
I want to sort this array like using ref value
$arr[2]['ref']=4;
$arr[2]['name']='name2';
$arr[0]['ref']=5;
$arr[0]['name']='name0';
$arr[1]['ref']=6;
$arr[1]['name']='name1';
$arr[4]['ref']='9';
$arr[4]['name']='name4';
$arr[3]['ref']='';
$arr[3]['name']='name3';
$arr[5]['ref']=''
$arr[5]['name']='name5'
i tried
uasort($arr, function($a, $b){
return $a['ref'] - $b['ref'];
});
But '' values are coming at the beginning. How can I push '' down.
Thanks in advance. I am beginner. please excuse me if i am asking very simple question
This will do the job:
uasort($arr, function($a, $b){
if ($a['ref'] == "") return 1;
if ($b['ref'] == "") return -1;
return $a['ref'] - $b['ref'];
});
You could try
uasort($arr, function($a, $b){
return -($a['ref'] - $b['ref']);
});
You can add empty values to the end of array using this:
uasort($arr, function($a, $b){
return $a['ref'] - $b['ref'];
});
//strip empties and move to end
foreach ($arr as $key => $value)
{
if ($value['ref'] == "")
{
unset($arr[$key]);
$arr[] = $value;
}
}
// rebuild array index
$arr = array_values($arr);
Output:
Array
(
[0] => Array
(
[ref] => 4
[name] => name2
)
[1] => Array
(
[ref] => 5
[name] => name0
)
[2] => Array
(
[ref] => 6
[name] => name1
)
[3] => Array
(
[ref] => 9
[name] => name4
)
[4] => Array
(
[ref] =>
[name] => name5
)
[5] => Array
(
[ref] =>
[name] => name3
)
)
I've decoded a JSON result from a server request and now need to sort based on the [name] field from the array. The deserialized code looks like this (snippet)
Array
(
[items] => Array
(
[0] => Array
(
[houseTypes] => Array
(
[0] => 2
[1] => 3
[2] => 4
)
[id] => 1
[name] => Aberdeen
[isLive] =>
)
[1] => Array
(
[houseTypes] => Array
(
[0] => 2
[1] => 3
[2] => 4
)
[id] => 2
[name] => Aberystwyth
[isLive] =>
There is no guarantee that the data coming down from the server will by alphabetical, so I need to sort based on the name.
I've tried using sort, assort and ksort, but none are showing correctly.
Is there a simple way to do this?
do it simple,
try this:
function cmp($a,$b)
{
if($a['name'] == $b['name'])
return 0;
return ($a['name'] < $b['name']) ? -1 : 1;
}
uasort($yourarray['items'],'cmp');
print_r($yourarray);
you can try with usort.See this http://php.net/manual/en/function.usort.php
I use this:
function subval_sort($a,$subkey) {
foreach($a as $k=>$v) {
$b[$k] = strtolower($v[$subkey]);
}
asort($b);
foreach($b as $key=>$val) {
$c[] = $a[$key];
}
return $c;
}
$users = subval_sort($users,'name');
So I am looking to sort the multi dimensional array below by "fk_page_id" ascending. Does anyone have any pointers. I think usort() is where I have to look but it seems like I cant find anyone with my specific array structure.
Array
(
[0] => Array
(
[title] => subpage of subpage!
[id] => 5
[long_title] =>
[fk_page_id] => 4
)
[1] => Array
(
[title] => about us subpage
[id] => 4
[long_title] =>
[fk_page_id] => 2
)
[2] => Array
(
[title] => about us
[id] => 2
[long_title] =>
[fk_page_id] => 1
)
)
function cmp($a, $b) {
if($a['fk_page_id'] == $b['fk_page_id']) {
return 0;
} else {
return $a['fk_page_id'] < $b['fk_page_id'] ? -1 : 1;
}
}
usort($yourarray, 'cmp');
if you're using PHP 5.3+:
define(ASC,1);
define(DESC,-1);
function colsort($array,$col,$order=ASC) {
usort(
$array,
function($a,$b) use($col,$order) {
return strcmp($a[$col],$b[$col])*$order;
}
);
return $array;
}
colsort($x,'fk_page_id');