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 do not know what is wrong with my php code. I want to have an Associative Array in the format. When I run my code I get this data. [KY] is an array in the [OH] array.
Array ( [Oh] => Array ( [state] => Oh ) [income] => 100 [count] => 1 [Ky] => Array ( [state] => Ky ) )
Array (
[OH] => Array
( [income] =>
[count] =>
)
[KY] => Array
( [income] =>
[count] =>
)
Here is my code
Example data in $array
Array ( [0] => Array (
[SurveyDate] => 1952-06-21
[Income] => 100
[CountyState] => Hamilton|Oh
[count] => 1 ) )
function update_array_value3( $array )
{
foreach ($array as $row)
{
$arrCountyState = explode( "|", $row['CountyState'] );
$key = $arrCountyState[1]; // OH or KY
if( !isset( $_SESSION['sIncome'][$key] ) )
{
$_SESSION['sIncome'][$key]['state'] = $key;
$_SESSION['sIncome'][$key]['income'] = $row['Income'];
$_SESSION['sIncome'][$key]['count'] = 1;
} else
{
$_SESSION['sIncome'][$key]['state'] = $key;
$_SESSION['sIncome'][$key]['income'] += $row['Income'];
$_SESSION['sIncome'][$key]['count'] += 1;
}
}
I can't tell you the root cause of the problem simply based on this snippet of code, but it seems $row either doesn't contain the data you expect it to, or doesn't contain any data.
In your code you reference $row['CountyState'], yet I don't see any array item called CountyState in $array.
Also, I'm not sure whether or not this is intentional, but in your foreach() loop it looks like $_SESSION['sIncome']['income'] and $_SESSION['sIncome']['count'] are being overwritten. Each time the loop encounters a new $key, it will overwrite those values.
I have an array like that:
printr_($photos);
======
Array
(
[0] => Array
(
[path] => site:photos/photo-1.jpg
[data] => Array
(
[PhotoTitle] => Mega title
[PhotoDate] => 2015
[FlickrURL] => xxx
[Portrait] =>
[slug] => mega-title
)
)
[1] => Array
(
[path] => site:photos/photo-2.jpg
[data] => Array
(
[PhotoTitle] => Photo title
[PhotoDate] => 2001
[FlickrURL] => xxx
[Portrait] =>
[slug] => photo-title
)
)
...
I would like to get the array index from a string (which is the slug from my browser current URL).
Tried that solution but I got an error (Undefined index: data […] on line 95)
/*
** Search in array
*/
function arraySearch($array, $field, $search){
foreach($array as $key => $value){
if ($value[$field] === $search)
return $key;
}
return false;
}
// Line 95
$photo_index = $photos[arraySearch($photos["data"], "slug", "mega-title")];
This should work PHP >= 5.5:
$key = array_search('mega-title', array_column(array_column($photos, 'data'), $slug));
$photo_index = $photos[$key];
The $photos variable does not have a key 'data', at least not by the print output. It has keys 1, 2, 3 etc.So $photos["data"] simply does not exist.
As to the search, I'm not 100% sure what you want to do, but I assume you want to get the index of the photo which $field in data equals $search, so that would be
/*
** Search in array
*/
function arraySearch($array, $field, $search){
foreach($array as $key => $value){
if ($value["data"][$field] === $search)
return $key;
}
return false;
}
and you would use it
$photo_index = $photos[arraySearch($photos, "slug", "mega-title")];
Im creating an array of products, each with an ID and score:
$savedProducts = array( 'product' => array("product_id" => $product_id,"product_score" => $score));
I want to be able to update the score by using the product_id as identifier.
I've tried:
foreach($savedProducts as $key => $val)
{
if ($val == $property_id )
{
$savedProducts[$key] = $score;
break;
}
}
Which keeps adding a new array item, rather than updating the original.
I think the issue is that my initial array setup then doesn't match the edited one.
Initial array:
Array
(
[product] => Array
(
[product_id] => 125026
[product_score] => 5
)
)
After trying to update score:
Array
(
[0] => Array
(
[product] => Array
(
[product_id] => 125026
[product_score] => 4
)
)
[1] => Array
(
[0] => Array
(
[product] => Array
(
[product_id] => 125026
[product_score] => 4
)
)
)
)
So it keeps addding elements, rather than updating the existing.
with PHP 5.5 use:
$savedProducts = array_column($savedProducts, NULL, 'product_id');
then you can access your product with:
$savedProducts[$product_id]
Please try this
foreach($savedProducts as $key => $val)
{
if($val['product_id'] == $property_id)
{
$savedProperties[$key]['product_score'] = $score;
break;
}
}
So My problem is:
I want to create nested array from string as reference.
My String is "res[0]['links'][0]"
So I want to create array $res['0']['links']['0']
I tried:
$result = "res[0]['links'][0]";
$$result = array("id"=>'1',"class"=>'3');
$result = "res[0]['links'][1]";
$$result = array("id"=>'3',"class"=>'9');
when print_r($res)
I see:
<b>Notice</b>: Undefined variable: res in <b>/home/fanbase/domains/fanbase.sportbase.pl/public_html/index.php</b> on line <b>45</b>
I need to see:
Array
(
[0] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 1
[class] => 3
)
)
)
[1] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 3
[class] => 9
)
)
)
)
Thanks for any help.
So you have a description of an array structure, and something to fill it with. That's doable with something like:
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
// unoptimized, always uses strings
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
array_create( $res, "[0]['links'][0]", array("id"=>'1',"class"=>'3') );
array_create( $res, "[0]['links'][1]", array("id"=>'3',"class"=>'9') );
Note how the array name itself is not part of the structure descriptor. But you could theoretically keep it. Instead call the array_create() function with a $tmp variable, and afterwards extract() it to achieve the desired effect:
array_create($tmp, "res[0][links][0]", array(1,2,3,4,5));
extract($tmp);
Another lazy solution would be to use str_parse after a loop combining the array description with the data array as URL-encoded string.
I have a very stupid way for this, you can try this :-)
Suppose your string is "res[0]['links'][0]" first append $ in this and then put in eval command and it will really rock you. Follow the following example
$tmp = '$'.'res[0]['links'][0]'.'= array()';
eval($tmp);
Now you can use your array $res
100% work around and :-)
`
$res = array();
$res[0]['links'][0] = array("id"=>'1',"class"=>'3');
$res[0]['links'][0] = array("id"=>'3',"class"=>'9');
print_r($res);
but read the comments first and learn about arrays first.
In addition to mario's answer, I used another function from php.net comments, together, to make input array (output from jquery form serializeArray) like this:
[2] => Array
(
[name] => apple[color]
[value] => red
)
[3] => Array
(
[name] => appleSeeds[27][genome]
[value] => 201
)
[4] => Array
(
[name] => appleSeeds[27][age]
[value] => 2 weeks
)
[5] => Array
(
[name] => apple[age]
[value] => 3 weeks
)
[6] => Array
(
[name] => appleSeeds[29][genome]
[value] => 103
)
[7] => Array
(
[name] => appleSeeds[29][age]
[value] => 2.2 weeks
)
into
Array
(
[apple] => Array
(
[color] => red
[age] => 3 weeks
)
[appleSeeds] => Array
(
[27] => Array
(
[genome] => 201
[age] => 2 weeks
)
[29] => Array
(
[genome] => 103
[age] => 2.2 weeks
)
)
)
This allowed to maintain numeric keys, without incremental appending of array_merge. So, I used sequence like this:
function MergeArrays($Arr1, $Arr2) {
foreach($Arr2 as $key => $Value) {
if(array_key_exists($key, $Arr1) && is_array($Value)) {
$Arr1[$key] = MergeArrays($Arr1[$key], $Arr2[$key]);
}
else { $Arr1[$key] = $Value; }
}
return $Arr1;
}
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
$input = $_POST['formData'];
$result = array();
foreach ($input as $k => $v) {
$sub = array();
array_create($sub, $v['name'], $v['value']);
$result = MergeArrays($result, $sub);
}