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.
Related
I am trying to convert a flat array into multidimensional array based on 'parent' and look a lot of examples and get good results but have 1 issue. I am missing last time of the array.
first i created an flat array
$service_arr = array();
foreach( $order_info[0]['service'] as $ordered_service ) {
$s_id = $ordered_service['id'];
$s_name = $ordered_service['name'];
$s_qty = $ordered_service['qty'];
$s_price = $ordered_service['price'];
$s_parent = gp_get_item_parent( $s_id ); // return parent_id of the element.
$service_arr[] = array(
'id' => $s_id,
'name' => $s_name,
'qty' => $s_qty,
'price' => $s_price,
'parent' => $s_parent
);
}
and this return's a flat array
Result:
Array
(
[0] => Array
(
[id] => 29
[name] => Another Facial
[qty] => 1
[price] => 1800
[parent] => 16
)
[1] => Array
(
[id] => 17
[name] => Facial 1
[qty] => 1
[price] => 2000
[parent] => 16
)
[2] => Array
(
[id] => 26
[name] => Addon
[qty] => 1
[price] => 500
[parent] => 17
)
[3] => Array
(
[id] => 39
[name] => Another Addon
[qty] => 1
[price] => 150
[parent] => 17
)
[4] => Array
(
[id] => 18
[name] => Facial 2
[qty] => 1
[price] => 2000
[parent] => 16
)
[5] => Array
(
[id] => 38
[name] => Nice Facial
[qty] => 1
[price] => 3000
[parent] => 16
)
[6] => Array
(
[id] => 21
[name] => Massage 2
[qty] => 1
[price] => 6000
[parent] => 14
)
)
Converting flat into multidimension array:
function create_tree_array( &$list, &$output, $parent_id ) {
if ( ! is_array( $list ) ) {
return;
}
if ( ! is_array( $output ) ) {
return;
}
foreach( $list as $i => $item ) {
if ( $item['parent'] == $parent_id ) {
$item['addon'] = array();
create_tree_array( $list, $item['addon'], $item['id'] );
$output[] = $item;
}
}
}
And using this function like
$services_tree = array();
create_tree_array( $service_arr, $services_tree, $service_arr[0]['parent'] );
Its working but the issue is that its missing last item of array:
[6] => Array (
[id] => 21
[name] => Massage 2
[qty] => 1
[price] => 6000
[parent] => 14
)
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',
)
This is my array:
Array
(
[0] => Array
(
[entity_id] => 1
[value] => new
[label] => New
)
[1] => Array
(
[entity_id] => 3
[value] => pending_payment
[label] => Pending Payment
)
[2] => Array
(
[entity_id] => 4
[value] => pending_paypal
[label] => Pending Paypal
)
[3] => Array
(
[entity_id] => 5
[value] => processing
[label] => Processing
)
[4] => Array
(
[entity_id] => 6
[value] => complete
[label] => Complete
)
[5] => Array
(
[entity_id] => 7
[value] => canceled
[label] => Canceled
)
[6] => Array
(
[entity_id] => 8
[value] => closed
[label] => Closed
)
[7] => Array
(
[entity_id] => 9
[value] => holded
[label] => Holded
)
[8] => Array
(
[entity_id] => 10
[value] => payment_review
[label] => Payment Review
)
[9] => Array
(
[entity_id] => 11
[value] => new
[label] => New
)
[10] => Array
(
[entity_id] => 13
[value] => pending_payment
[label] => Pending Payment
)
UPDATE This is the result of the print_r.
As you can see the array[0] with array[6] are the same. Also the array[7] with the array[1]. How can I get rid of one of them ? thx
I tried smth like this:
$input = $my_array
$temp = $input;
foreach ( $temp as &$data ) {
unset($data['id']);
}
$output = array_intersect_key($input, array_unique($temp));
but with no any result :( .
$result = array();
foreach ($myArray as $array) {
if (isset($result[$array['value']])) {
continue;
}
$result[$array['value']] = $array;
}
print_r($result);
Hey Attila this should help.
Your $my_array is renamed in this example into $wholeArray. And I thought it woulf be enough to compare the labels:
$index=0;
$length = count($wholeArray);
foreach($wholeArray as $arrayElement){
$temp = $arrayElement['label'];
$index++;
for($i = $index; $i < $length; $i++){
if($wholeArray[$i]['label'] == $temp){
unset($wholeArray[$i]);
$length --;
}
}
}
If you have any questions to the code feel free to ask :)
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()