I'm trying to insert high level product review data to SKU records but am stuck with trying to get the average value of duplicated keys.
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
[4] => Array
(
[sku] => F30W/T8/830/POLYLUX
[rating] => 2
)
[5] => Array
(
[sku] => 70835
[rating] => 4
)
)
I would like to get the average rating for the duplicate skus so expected output would be:
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 4.5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
...
)
I have the below loop which is summing the duplicates but I'm struggling to get the average
foreach ($reviews as $val) {
if (!isset($result[$val['sku']]))
{
$result[$val['sku']] = $val;
}
else{
$result[$val['sku']]['rating'] += $val['rating'];
#This will sum the duplicated ratings but I need to divide the sum here by the number of times the 'sku' index was duplicated so in the example 9/2 = 4.5
}
}
thanks in advance!
What about adding a count field to your result array...
foreach ($reviews as $val) {
if (!isset($result[$val['sku']]))
{
$result[$val['sku']] = $val;
$result[$val['sku']]["count"] = 1;
}
else{
$result[$val['sku']]['rating'] += $val['rating'];
$result[$val['sku']]["count"] ++;
}
}
foreach($result as $k => $v) {
$result[$k]['avg'] = $v['rating']/$v['count'];
}
This should work for you:
foreach ($reviews as $val) {
if (!isset($result[$val['sku']]))
{
$result[$val['sku']] = array('rating' => $val['rating'], 'count' => 1);
}
else{
$result[$val['sku']]['rating'] += $val['rating'];
$result[$val['sku']]['count']++;
}
}
foreach ($result as &$val) {
$val['average'] = $val['rating'] / $val['count'];
}
Be aware, if this data is coming from a database, there are much easier ways to do this, by using GROUP BY statements.
[akshay#localhost tmp]$ cat test.php
<?php
$array = array (
0 =>
array (
'sku' => '70835',
'rating' => '5',
),
1 =>
array (
'sku' => 'F6W/35',
'rating' => '5',
),
2 =>
array (
'sku' => '36865',
'rating' => '5',
),
3 =>
array (
'sku' => '36835',
'rating' => '5',
),
4 =>
array (
'sku' => 'F30W/T8/830/POLYLUX',
'rating' => '2',
),
5 =>
array (
'sku' => '70835',
'rating' => '4',
),
);
$final=$count=array();
foreach($array as $v)
{
if(isset($final[$v['sku']]))
{
$final[$v['sku']]['rating'] += $v['rating'];
$count[$v['sku']]++;
}else
{
$final[$v['sku']] = $v;
$count[$v['sku']] = 1;
}
}
array_map( function($a, $b) use (&$final){ $final[$a]['rating']/=$b; }, array_keys($count),array_values($count));
unset($count);
// Input
print_r($array);
// Output
print_r( array_values($final));
?>
Output
[akshay#localhost tmp]$ php test.php
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
[4] => Array
(
[sku] => F30W/T8/830/POLYLUX
[rating] => 2
)
[5] => Array
(
[sku] => 70835
[rating] => 4
)
)
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 4.5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
[4] => Array
(
[sku] => F30W/T8/830/POLYLUX
[rating] => 2
)
)
Related
I am facing problem In grouping array with the Key:-
I have an php array Which has following elecment in it.
$array = array(
'0' => array ( 'id' => 'food,Travel', 'names' => 'chimpanzee' ),
'1' => array ( 'id' => 'food', 'name' => 'meeting' ),
'2' => array ( 'id' => 'Z1', 'name' => 'dynasty' ),
'3' => array ( 'id' => 'X', 'name' => 'chocolate' ),
'4' => array ( 'id' => 'Travel', 'name' => 'bananas' ),
'5' => array ( 'id' => 'Travel', 'name' => 'fantasy' ),
'6' => array ( 'id' => 'Travel', 'name' => 'football' )
);
When I try with following code:-
$newarray= array();
foreach($array as $key => $value){
$newarray[$value['id']][$key] = $value;
}
I am getting below result Array Here food,travel is created another array but I want to please those to respective category "Food goes to food" and travel goes to travel"
(
[food,Travel] => Array
(
[0] => Array
(
[id] => food,Travel
[names] => chimpanzee
)
)
[food] => Array
(
[1] => Array
[id] => food,Travel
[names] => chimpanzee
)
(
[id] => food
[name] => meeting
)
)
[Z1] => Array
(
[2] => Array
(
[id] => Z1
[name] => dynasty
)
)
[X] => Array
(
[3] => Array
(
[id] => X
[name] => chocolate
)
)
[Travel] => Array
(
[4] => Array
(
[id] => Travel
[name] => bananas
)
[5] => Array
(
[id] => Travel
[name] => fantasy
)
[6] => Array
(
[id] => Travel
[name] => football
)
)
)
But I am want following result:- Food should Go to food category and travels should go to travels category like:-
Array
(
[food] => Array
(
// Food should come at food category
[0] => Array
(
[id] => food
[names] => chimpanzee
)
)
(
[1] => Array
(
[id] => food
[name] => meeting
)
)
[Z1] => Array
(
[2] => Array
(
[id] => Z1
[name] => dynasty
)
)
[X] => Array
(
[3] => Array
(
[id] => X
[name] => chocolate
)
)
[Travel] => Array
(
( // Travel should come at travel category
[0] => Array
(
[id] => food
[names] => chimpanzee
)
)
[4] => Array
(
[id] => Travel
[name] => bananas
)
[5] => Array
(
[id] => Travel
[name] => fantasy
)
[6] => Array
(
[id] => Travel
[name] => football
)
)
)
When id has ,, just explode it, check the demo
$result = [];
foreach($array as $k => $v){
if(strpos($v["id"],",")) {
$ids = explode(",", $v["id"]);
foreach ($ids as $id) {
$result[$id][$k] = $v;
}
}else{
$result[$v["id"]][$k] = $v;
}
}
var_dump($result);
No need to make it complex, like some have suggested, use explode()
https://3v4l.org/jVK6j
$newarray= [];
foreach($array as $key => $value) {
if(is_array(explode(",", $value["id"]))) {
foreach(explode(",", $value["id"]) as $category) {
$newarray[$category][$key] = $value;
$newarray[$category][$key]["id"] = $category;
}
} else {
$newarray[$value["id"]][$key] = $value;
}
}
var_dump($newarray);
You could even remove $key since these will be auto incremented.
foreach($array as $value) {
if(is_array(explode(",", $value["id"]))) {
foreach(explode(",", $value["id"]) as $category) {
$value["id"] = $category;
$newarray[$category][] = $value;
}
} else {
$newarray[$value["id"]][] = $value;
}
}
Assuming I have an array and recursively want to do some task. I have spent one day for this unable to solve this. May be my logic is not good.
Any help on how to do such thing in an efficient way would save my days.
I have an array with n level deep, looking like:
Array
(
[0] => Array
(
[name] => user1
[email] => user1#demo.com
[depth] => 1
)
[1] => Array
(
[name] => user2
[email] => user2#demo.com
[depth] => 1
[0] => Array
(
[0] => Array
(
[name] => user2.1
[email] => user2.1#demo.com
[depth] => 2
)
)
)
[2] => Array
(
[name] => user3
[email] => user3#demo.com
[depth] => 1
[0] => Array
(
[0] => Array
(
[name] => user3.1
[email] => user3.1#demo.com
[depth] => 2
[0] => Array
(
[0] => Array
(
[name] => user3.1.1
[email] => user3.1.1#demo.com
[depth] => 3
)
)
)
[1] => Array
(
[name] => user3.2
[email] => user3.2#demo.com
[depth] => 2
)
)
)
)
I want to change above array in exactly this format:
array(
0 => array(
'name' => 'user1',
),
1 => array(
'name' => 'user2',
'children' => array(
0 => array(
'name' => 'user2.1',
) ,
) ,
) ,
2 => array(
'name' => 'user3',
'children' => array(
0 => array(
'name' => 'user3.1',
'children' => array(
0 => array(
'name' => 'user3.1.1',
) ,
) ,
) ,
1 => array(
'name' => '3.2',
)
) ,
) ,
)
Edited:
I am using this code and working fine if i want to show data in tree format but unable to push data into array as i want.
function displayArrayRecursively($arr, $indent='') {
if ($arr) {
foreach ($arr as $key => $value) {
if (is_array($value)) {
displayArrayRecursively($value, $indent . '-->');
} else {
if ($key == 'name')
{
echo "$indent $value <br>";
}
else {
continue;
}
}
}
}
}
displayArrayRecursively($userListArray);
Can anyone suggest me how to do this?
Thank you
This function will do what you want:
function process_nodes($nodes) {
$new = array();
foreach ($nodes as $node) {
$new[] = array('name' => $node['name']);
if (isset($node[0])) {
$new[count($new)-1]['children'] = process_nodes($node[0]);
}
}
return $new;
}
print_r(process_nodes($data));
Output:
Array
(
[0] => Array
(
[name] => user1
)
[1] => Array
(
[name] => user2
[children] => Array
(
[0] => Array
(
[name] => user2.1
)
)
)
[2] => Array
(
[name] => user3
[children] => Array
(
[0] => Array
(
[name] => user3.1
[children] => Array
(
[0] => Array
(
[name] => user3.1.1
)
)
)
[1] => Array
(
[name] => user3.2
)
)
)
)
Sorry I don't know the actual title of my question. I have a problem with a php array.
my array is like :
$Array =
(
[0] => Array
(
[Product] => Array
(
[cat_id] => 7
[subcat_id] => 1
)
)
[1] => Array
(
[Product] => Array
(
[cat_id] => 7
[subcat_id] => 1
)
)
[2] => Array
(
[Product] => Array
(
[cat_id] => 8
[subcat_id] => 2
)
)
[3] => Array
(
[Product] => Array
(
[cat_id] => 9
[subcat_id] => 3
)
)
[4] => Array
(
[Product] => Array
(
[cat_id] => 9
[subcat_id] => 3
)
)
)
Now I want to insert
[Subcat]=>'changed'
if the subcat_id is changed . How to check if the subcat_id is changed on the next key value.please help.
I have tried this :
$sub_cat_last = '';
foreach ($Array as $key => $p) {
$sub_cat = $p['Product']['subcat_id'];
if($sub_cat != $sub_cat_last){
$Array[$key]['Subcat'] = 'change';
$sub_cat_last = $p['Product']['subcat_id'];
}
}
But not working properly.
I want my array like :
Array
(
[0] => Array
(
[Product] => Array
(
[cat_id] => 7
[subcat_id] => 1
)
)
[1] => Array
(
[Product] => Array
(
[cat_id] => 7
[subcat_id] => 1
)
)
[2] => Array
(
[Product] => Array
(
[Subcat] => change
)
)
[3] => Array
(
[Product] => Array
(
[cat_id] => 8
[subcat_id] => 2
)
)
[4] => Array
(
[Product] => Array
(
[Subcat] => change
)
)
[5] => Array
(
[Product] => Array
(
[cat_id] => 9
[subcat_id] => 3
)
)
[6] => Array
(
[Product] => Array
(
[cat_id] => 9
[subcat_id] => 3
)
)
[7] => Array
(
[Product] => Array
(
[Subcat] => change
)
)
)
Is this possible.
How about:
$Array = Array(
0 => Array(
'Product' => Array(
'cat_id' => 7,
'subcat_id' => 1,
)
),
1 => Array(
'Product' => Array(
'cat_id' => 7,
'subcat_id' => 1,
)
),
2 => Array(
'Product' => Array(
'cat_id' => 8,
'subcat_id' => 2,
)
),
);
$prev_id = $Array[0]['Product']['subcat_id'];
$result = array(0 => $Array[0]);
for($i = 1; $i < count($Array); $i++) {
if ($Array[$i]['Product']['subcat_id'] != $prev_id) {
$result[]['Product']['subcat'] = 'change';
}
$result[] = $Array[$i];
$prev_id = $Array[$i]['Product']['subcat_id'];
}
$result[]['Product']['subcat'] = 'change';
print_r($result);
Output:
Array
(
[0] => Array
(
[Product] => Array
(
[cat_id] => 7
[subcat_id] => 1
)
)
[1] => Array
(
[Product] => Array
(
[cat_id] => 7
[subcat_id] => 1
)
)
[2] => Array
(
[Product] => Array
(
[subcat] => change
)
)
[3] => Array
(
[Product] => Array
(
[cat_id] => 8
[subcat_id] => 2
)
)
[4] => Array
(
[Product] => Array
(
[subcat] => change
)
)
)
save previous cat_id and subcat_id, check when cat_id added one. This suppose you cat_id is in sequence, added 0 or 1 each step.
$preValue = array('cat_id' => 0, 'subcat_id' => 0);
$changed = false;
foreach ($Array as $item) {
$product = $item['Product'];
if($preValue['cat_id'] != 0 && $product['cat_id'] == $preValue['cat_id'] + 1 && $product['subcat_id'] != $preValue['subcat_id'])
{
$changed = true;
break;
}
$preValue['cat_id'] = $product['cat_id'];
$preValue['subcat_id'] = $product['subcat_id'];
}
This will do what you are looking for:
$old_subcat_id = null;
$newArray = Array();
foreach ($Array as $item) {
$subcat_id = $item['Product']['subcat_id'];
if ($subcat_id != $old_subcat_id) {
//do something here
echo "subcat_id has changed from [$old_subcat_id] to [$subcat_id]<br>";
if ($old_subcat_id != null) {
$newArray[]['Product']['Subcat'] = 'change';
}
$old_subcat_id = $subcat_id;
}
$newArray[] = $item;
}
I have one array in two format. I want to change array from
Array
(
[step_number] => 4
[app_id] => Array
(
[0] => 2
[1] => 3
)
[formdata] => Array
(
[0] => Array
(
[name] => app_id[]
[value] => 2
)
[1] => Array
(
[name] => app_id[]
[value] => 3
)
[2] => Array
(
[name] => fieldval[2][2][]
[value] => 1
)
[3] => Array
(
[name] => fieldval[3][3][]
[value] => 200
)
[4] => Array
(
[name] => fieldval[3][3][]
[value] => day
)
[5] => Array
(
[name] => title
[value] => new plan
)
[6] => Array
(
[name] => feature_plan
[value] => 3
)
[7] => Array
(
[name] => plan_type
[value] => free
)
[8] => Array
(
[name] => price
[value] =>
)
[9] => Array
(
[name] => sell_type
[value] => us
)
)
)
this format to
Array
(
[app_id] => Array
(
[0] => 2
[1] => 3
)
[fieldval] => Array
(
[2] => Array
(
[2] => Array
(
[0] => 1
)
)
[3] => Array
(
[3] => Array
(
[0] => 200
[1] => day
)
)
)
[title] => new plan
[feature_plan] => 3
[plan_type] => free
[price] =>
[sell_type] => us
)
these are are one array into two format. i have data in to first array format and i want to change that format to second array type format.
please tell me how i am trying this for 2 days but not succeed.
Here is a function you could use to produce that conversion:
function convert_formdata($input) {
$output = array();
foreach($input['formdata'] as $data) {
$keys = preg_split("#[\[\]]+#", $data['name']);
$value = $data['value'];
$target = &$output;
foreach($keys as $key) {
// Get index for "[]" reference
if ($key == '') $key = count($target);
// Create the key in the parent array if not there yet
if (!isset($target[$key])) $target[$key] = array();
// Move pointer one level down the hierarchy
$target = &$target[$key];
}
// Write the value at the pointer location
$target = $value;
}
return $output;
}
You would call it like this:
$output = convert_formdata($input);
See it run on eval.in for the given input. The output is:
array (
'app_id' =>
array (
0 => 2,
1 => 3,
),
'fieldval' =>
array (
2 =>
array (
2 =>
array (
0 => 1,
),
),
3 =>
array (
3 =>
array (
0 => 200,
1 => 'day',
),
),
),
'title' => 'new plan,',
'feature_plan' => 3,
'plan_type' => 'free',
'price' => NULL,
'sell_type' => 'us',
)
I have this array $all_zones that comes sometimes with missing keys and values and I would like to fill the array with empty values for the messing keys, here's the array:
Array
(
[0] => Array
(
[id_zone] => 1
[name] => Europe
[price] => Array
(
[0] => 3.00
[1] => 6.00
)
[id_delivery] => Array
(
[0] => 1
[1] => 2
)
)
[1] => Array
(
[id_zone] => 3
[name] => Asia
)
[2] => Array
(
[id_zone] => 4
[name] => Africa
[price] => Array
(
[0] => 3.00
[1] => 6.00
)
[id_delivery] => Array
(
[0] => 3
[1] => 4
)
)
[3] => Array
(
[id_zone] => 5
[name] => Oceania
)
)
The thing is the $all_zones[$key]['price'] depend on how many ranges there's for each Zone, inthis case $range_count = count($all_ranges); will display 2, so I'd like to fill the missing keys for 2 times : Here's the output:
Array
(
[0] => Array
(
[id_zone] => 1
[name] => Europe
[price] => Array
(
[0] => 3.00
[1] => 6.00
)
[id_delivery] => Array
(
[0] => 1
[1] => 2
)
)
[1] => Array
(
[id_zone] => 3
[name] => Asia
[price] => Array
(
[0] =>
[1] =>
)
[id_delivery] => Array
(
[0] =>
[1] =>
)
)
[2] => Array
(
[id_zone] => 4
[name] => Africa
[price] => Array
(
[0] => 3.00
[1] => 6.00
)
[id_delivery] => Array
(
[0] => 3
[1] => 4
)
)
[3] => Array
(
[id_zone] => 5
[name] => Oceania
[price] => Array
(
[0] =>
[1] =>
)
[id_delivery] => Array
(
[0] =>
[1] =>
)
)
)
Here's what I've tried so far and didn't succeed:
$range_count = count($all_ranges);
$i=0;
foreach ($all_zones as $key => $value) {
if(isset($value['id_zone']) && isset($value['name']) && (!isset($value['price']) || !isset($value['id_delivery']))){
if($range_count>$i){
$disabled[]=$key;
$all_zones[$key]['price'][] = '';
$all_zones[$key]['id_delivery'][] = '';
}
$i++;
}
}
Any help with this? Much appreciated.
try this
$range_count = count($all_ranges);
foreach ($all_zones as $key => $value) {
if(isset($value['id_zone']) && isset($value['name']) && (!isset($value['price']) || !isset($value['id_delivery']))){
$disabled[]=$key;
if((!isset($value['price']))
{
for($i=0; $i<$range_count<$i++)
{
$all_zones[$key]['id_delivery'][] = '';
}
}
if((!isset($value['id_delivery']))
{
for($i=0; $i<$range_count<$i++)
{
$all_zones[$key]['id_delivery'][] = '';
}
}
}
}
You might have operator precedence problem.
( (!isset($value['price']) || !isset($value['id_delivery'])) )
The way to do this is to loop through the array, with an array_merge() on each array within the parent array to set your 'defaults'.
$zone_template = array(
'id_zone' => '',
'name' => '',
'price' => array(
0 => '',
1 => ''
),
'id_delivery' = array(
0 => '',
1 => ''
)
);
foreach ($all_zones as $zone) {
array_merge($zone_template, $zone);
}
Can also be done with array_walk()