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;
}
Related
How to get list all multidimensional array with parent index. All index in each level is unique and i want to show all list with the level.
example my arrays:
Array(
[1] => Array(
[2] => Array(
[3] =>
[4] =>
[7] =>
)
)
[6] => Array(
[11] => Array(
[12] => Array(
[17] =>
)
)
)
[2] => Array(
[13] => Array(
[14] =>
)
)
)
I want to get output like this:
Array
(
[1]=array([level] = 1)
[2]=array([level] = 2)
[3]=array([level] = 3)
[4]=array([level] = 3)
[7]=array([level] = 3)
[6]=array([level] = 1)
[11]=array([level] = 2)
[12]=array([level] = 3)
[17]=array([level] = 4)
...
)
Here is a solution using a recursive function. Assuming your array will have a NULL value if there is no more child/nested arrays.
$arr = array(1 => array(2 => array(3 => NULL,
4 => NULL,
7 => NULL )),
6 => array(11 => array(12 => array(17 =>NULL))),
2 => array(13 => array(14 => NULL)));
$rslt_arr = array();
function traverse_arr($array, $level)
{
$level++;
foreach ($array as $key => $value){
if($value != NULL){
traverse_arr($value, $level);
}
$GLOBALS['rslt_arr'][$key]['level'] = $level;
}
}
traverse_arr($arr, 0);
echo '<pre>';
print_r($rslt_arr);
OUTPUT:
Array
(
[3] => Array
(
[level] => 3
)
[4] => Array
(
[level] => 3
)
[7] => Array
(
[level] => 3
)
[2] => Array
(
[level] => 1
)
[1] => Array
(
[level] => 1
)
[17] => Array
(
[level] => 4
)
[12] => Array
(
[level] => 3
)
[11] => Array
(
[level] => 2
)
[6] => Array
(
[level] => 1
)
[14] => Array
(
[level] => 3
)
[13] => Array
(
[level] => 2
)
)
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
)
)
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()
I have an array,
$arr=(
[0] => Array
(
[groupid] => 1
[groupname] => Red
[members] => Array
(
[0] => Array
(
[mid] => 9
[name] => Anith
)
[1] => Array
(
[mid] => 11
[name] => Aravind
)
[2] => Array
(
[mid] => 10
[name] => Lekshmi
)
)
)
[1] => Array
(
[groupid] => 2
[groupname] => Blue
[members] => Array
(
[0] => Array
(
[mid] => 6
[name] => Yamuna
)
[1] => Array
(
[mid] => 2
[name] => Kamala K
)
[2] => Array
(
[mid] => 13
[name] => Sooraj K
)
)
)
I want to check [mid] => 2 is in the array..If it exists
I want to delete it(ie. unset the array )-----
[1] => Array
(
[mid] => 2
[name] => Kamala K
)
;;;
eg:--unset($arr[1]['members'][2];
This should do the trick
foreach ($arr as $group => $subarray) {
foreach ($subarray['members'] as $k => $v) {
if ($v['mid'] == 2) {
unset($arr[$group]['members'][$k]);
break;
}
}
}
var_dump($arr);
If you feel like getting crafty, you could do something like this:
// note: requires PHP >= 5.3
foreach ($arr as $key => &$value) {
$value['members'] = array_filter(
$value['members'],
function($member) {
return $member['mid'] != 2;
}
);
}
var_dump($arr);
I have an array with values like:
Array
(
[0] => Array
(
[parent] => Basic
[parentId] => 1
[child] => Birthday
[childId] => 2
)
[1] => Array
(
[parent] => Basic
[parentId] => 1
[child] => Gender
[childId] => 3
)
[2] => Array
(
[parent] => Geo
[parentId] => 10
[child] => Current City
[childId] => 11
)
[3] => Array
(
[parent] => Known me
[parentId] => 5
[child] => My personality
[childId] => 7
)
[4] => Array
(
[parent] => Known me
[parentId] => 5
[child] => Best life moment
[childId] => 8
)
)
And I want to filter this array such that their filtration based on parent index, and the final result would be like:
Array
(
[0] => Array
(
[parent] => Basic
[parentId] => 1
[child] => Array
(
[0] => Birthday
[1] => Gender
)
)
[1] => Array
(
[parent] => Geo
[parentId] => 10
[child] => Array
(
[0] => Current City
)
)
[2] => Array
(
[parent] => Known me
[parentId] => 5
[child] => Array
(
[0] => My personality
[1] => Best life moment
)
)
)
For that I coded :
$filter = array();
$f = 0;
for ($i=0; $i<count($menuArray); $i++) {
$c = 0;
for( $b = 0; $b < count($filter); $b++ ){
if( $filter[$b]['parent'] == $menuArray[$i]['parent'] ){
$c++;
}
}
if ($c == 0) {
$filter[$f]['parent'] = $menuArray[$i]['parent'];
$filter[$f]['parentId'] = $menuArray[$i]['parentId'];
$filter[$f]['child'][] = $menuArray[$i]['child'];
$f++;
}
}
But it results :
Array
(
[0] => Array
(
[parent] => Basic
[parentId] => 1
[child] => Array
(
[0] => Birthday
)
)
[1] => Array
(
[parent] => Geo
[parentId] => 10
[child] => Array
(
[0] => Current City
)
)
[2] => Array
(
[parent] => Known me
[parentId] => 5
[child] => Array
(
[0] => My personality
)
)
)
Could anyone point out my missing LOC?
Try:
$filter = array();
foreach ($menuArray as $menu) {
if (!array_key_exists($menu['parent_id'], $filter)) {
$filter[$menu['parent_id']] = array(
'parent' => $menu['parent'],
'parent_id' => $menu['parent_id'],
'child' => array()
);
}
$filter[$menu['parent_id']]['child'][$menu['child_id']] = $menu['child'];
}
This will produce an array like:
Array
(
[1] => Array
(
[parent] => Basic
[parentId] => 1
[child] => Array
(
[2] => Birthday
[3] => Gender
)
)
[10] => Array
(
[parent] => Geo
[parentId] => 10
[child] => Array
(
[11] => Current City
)
)
[5] => Array
(
[parent] => Known me
[parentId] => 5
[child] => Array
(
[7] => My personality
[8] => Best life moment
)
)
)
Notice that the array indexes match the IDs. You can't loop this with a for loop but you can foreach ($filter as $parent_id=>$parent) correctly. If you want to you can change line 4 of my code to $filter['key_' . $menu['parent_id']] to force a string and a for loop will work
The next piece of code is completely untested, and based on the idea that it's sorted by parentId.
$filter = array();
$option = null;
for( $i = 0; $i < count( $menuArray ); $i++ ) {
if( count( $filter ) < 1 || $filter[count($filter)-1]['parentId'] != $menuArray['parentId'] ) {
if( $option != null ) {
$filter[] = $option;
}
$option = array(
"parent" => $menuArray[$i]['parent'],
"parentId" => $menuArray[$i]['parentId'],
"child" => array()
);
}
$option['child'][] = $menuArray[$i]['child'];
}
$filter[] = $option; // one last time, because we left the loop already.
unset( $option ); // we don't need it anymore.
What it does, it creates a $option for every parent. As soon as we hit the next parentId we add the current $option to the $filter array and create a new $option object.
All the children just keep getting added to the current $option.