How to Group a multidimensional array - php

How can I group the array based Name Menu Category and Name Menu ? Is there any native php functions are available to do this? I 've searched on google but not yet well understood
(int) 0 => array(
'MenuCategory' => array(
'name' => 'Products'
),
'Menu' => array(
'name' => 'A',
'url' => 'a'
),
'Sub' => array(
'name' => 'A1',
'url' => 'a1'
)
),
(int) 1 => array(
'MenuCategory' => array(
'name' => 'Products'
),
'Menu' => array(
'name' => 'A',
'url' => 'a'
),
'Sub' => array(
'name' => 'A2',
'url' => 'a2'
)
),
(int) 2 => array(
'MenuCategory' => array(
'name' => 'Products'
),
'Menu' => array(
'name' => 'B',
'url' => 'b'
),
'Sub' => array(
'name' => null,
'url' => null
)
),
(int) 3 => array(
'MenuCategory' => array(
'name' => 'Data'
),
'Menu' => array(
'name' => 'A',
'url' => 'a'
),
'Sub' => array(
'name' => null,
'url' => null
)
),
(int) 4 => array(
'MenuCategory' => array(
'name' => 'Data'
),
'Menu' => array(
'name' => 'B',
'url' => 'b'
),
'Sub' => array(
'name' => 'B1',
'url' => 'b1'
)
),
(int) 5 => array(
'MenuCategory' => array(
'name' => 'Data'
),
'Menu' => array(
'name' => 'C',
'url' => 'c'
),
'Sub' => array(
'name' => null,
'url' => null
)
),
(int) 6 => array(
'MenuCategory' => array(
'name' => 'Report'
),
'Menu' => array(
'name' => 'A',
'url' => 'a'
),
'Sub' => array(
'name' => null,
'url' => null
)
),
(int) 7 => array(
'MenuCategory' => array(
'name' => 'Report'
),
'Menu' => array(
'name' => 'B',
'url' => 'b'
),
'Sub' => array(
'name' => null,
'url' => null
)
),
(int) 8 => array(
'MenuCategory' => array(
'name' => 'Report'
),
'Menu' => array(
'name' => 'C',
'url' => 'c'
),
'Sub' => array(
'name' => null,
'url' => null
)
),
This is a result that will be issued later
Products
A
A1
A2
B
Data
A
B
B1
C
Report
A
B
C

if I assume your array variable name is $menu, try this code.
$new = array();
array_map(function($a) use(&$new){
if($a['Sub']['name'])
$new[$a['MenuCategory']['name']][$a['Menu']['name']][$a['Sub']['name']] = $a['Sub']['name'];
else
$new[$a['MenuCategory']['name']][$a['Menu']['name']] = $a['Menu']['name'];
}, $menu);
print_r($new);
and will output
Array
(
[Products] => Array
(
[A] => Array
(
[A1] => A1
[A2] => A2
)
[B] => B
)
[Data] => Array
(
[A] => A
[B] => Array
(
[B1] => B1
)
[C] => C
)
[Report] => Array
(
[A] => A
[B] => B
[C] => C
)
)
Hope this help.

Group them by level first
use foreach to sort them example
foreach ($input_arr as $key => &$entry) {
$level_arr[$entry['level']][$key] = $entry;
}

Related

php use array_slice in nested array

I have an array like this
$data = array(
'2021-08-31' => array( 'country_id' => array( '191' => array( '20098' ) ) ),
'2021-08-18' => array( 'country_id' => array( '214' => array( '14876' ) ) ),
'2021-07-12' => array( 'country_id' => array( '103' => array( '19709' ) ) ),
'2021-07-07' => array( 'country_id' => array( '206' => array( '9568' ) ) ),
'2021-06-28' => array( 'country_id' => array( '246' => array( '19561' ), '132' => array( '19277' ), '1' => array( '2816' ), '83' => array( '19530' ), '21' => array('3340'), '202' => array( '14136' ), '103' => array( '17006' ) ) ),
'2021-06-25' => array( 'country_id' => array( '99' => array( '14561' ), '102' => array( '26789' ), '21' => array( '7690' ), '21' => array( '242325' ), '11' => array('436432'), '999' => array( '43734' ), '768' => array( '34437' ) ) ),
);
Here I want to apply array_slice only for country_id element.
So lets say if I want to show first 6 elements of country id then it should something like this
$data = array(
'2021-08-31' => array( 'country_id' => array( '191' => array( '20098' ) ) ),
'2021-08-18' => array( 'country_id' => array( '214' => array( '14876' ) ) ),
'2021-07-12' => array( 'country_id' => array( '103' => array( '19709' ) ) ),
'2021-07-07' => array( 'country_id' => array( '206' => array( '9568' ) ) ),
'2021-06-28' => array( 'country_id' => array( '246' => array( '19561' ), '132' => array( '19277' ) ) ),
);
If I want to show elements from 3 to 9 then it should show something like this
$data = array(
'2021-07-12' => array( 'country_id' => array( '103' => array( '19709' ) ) ),
'2021-07-07' => array( 'country_id' => array( '206' => array( '9568' ) ) ),
'2021-06-28' => array( 'country_id' => array( '246' => array( '19561' ), '132' => array( '19277' ), '1' => array( '2816' ), '83' => array( '19530' ), '21' => array('3340') ) ),
);
So can someone tell me how to achieve this without changing key value pair of above array.
Any help and suggestions would be really appreciable.
Following logic might help you on your way. Just set the slice you'd like to extract with $start and $end and the result is stored in array $store:
// set your slice with start and end
$start = 3;
$end = 9;
$count = 0;
$store = []; // the result store
foreach($data as $date => $record) {
foreach($record['country_id'] as $k => $countryIds) {
foreach($countryIds as $id) {
$count++;
if($count >= $start && $count <= $end) $store[$date]['country_id'][$k] = $countryIds;
}
}
}
demo

How to merge multiple dimension array cakephp with two key

I just using function query() of cakePhp. The query will return array something like :
array(
(int) 0 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '11'
),
'cate_item' => array(
'price' => '150.000'
),
'item' => array(
'code' => '1'
)
),
(int) 1 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '1'
)
),
(int) 2 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '2'
)
),
(int) 3 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '1'
)
)
)
Now, I want to check if array have the same cate.date and item.code will merge array (in this case is elements 0,1 of my array). Output something like :
array(
(int) 0 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
(int) 0 => array (
'rel_data_category' => '11',
'price' => '150.000'
),
(int) 1 => array(
'rel_data_category' => '10',
'price' => '250.000'
)
),
'item' => array(
'code' => '1'
)
),
(int) 1 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
(int) 0 => array (
'rel_data_category' => '10'
'price' => '250.000'
)
),
'item' => array(
'code' => '2'
)
),
(int) 2 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
(int) 0 => array (
'rel_data_category' => '10'
'price' => '250.000'
)
),
'item' => array(
'code' => '1'
)
)
)
Please help!
To do that
First declare a variable which later you will store new merge array data
$filter_data = array();
then loop your existing array
foreach($items as $item) {
// do somethind
then create a function which check if item which same date and code not yet exist in the new array
// checker
if (!checkExist($item['cate']['date'], $item['item']['code'])) {
Create a variable for temporary data that will append to the new array later
$data = array(
'cate' => $item['cate'],
'item' => $item['item']
);
Then create loop again which will append all index item cate_detail and cate_item who have the same
date and code from the parent loop
}
}
So your code would be like this
$items = array(
(int) 0 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '11'
),
'cate_item' => array(
'price' => '150.000'
),
'item' => array(
'code' => '1'
)
),
(int) 1 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '1'
)
),
(int) 2 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '2'
)
),
(int) 3 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '1'
)
)
);
$filter_data = array();
foreach($items as $item) {
if (!checkExist($item['cate']['date'], $item['item']['code'])) {
$data = array(
'cate' => $item['cate'],
'item' => $item['item']
);
foreach($items as $detail) {
if ($detail['cate']['date'] == $item['cate']['date'] &&
$detail['item']['code'] == $item['item']['code']) {
$data['cate_detail'][] = array(
'rel_data_category' => $detail['cate_detail']['rel_data_category'],
'price' => $detail['cate_item']['price']
);
}
}
$filter_data[] = $data;
}
}
function checkExist($date, $code){
global $filter_data;
foreach($filter_data as $data) {
if ($data['cate']['date'] == $date &&
$data['item']['code'] == $code) {
return true;
}
}
return false;
}
pr($filter_data);
Demo
OR
$items = array(
(int) 0 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '11'
),
'cate_item' => array(
'price' => '150.000'
),
'item' => array(
'code' => '1'
)
),
(int) 1 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '1'
)
),
(int) 2 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '2'
)
),
(int) 3 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
),
'item' => array(
'code' => '1'
)
)
);
$filter_data = array();
$exists = array();
foreach($items as $item) {
$index_key = $item['cate']['date'].'-'.$item['item']['code'];
if (!isset($exists[$index_key])) {
$exists[$index_key] = 1;
$data = array(
'cate' => $item['cate'],
'item' => $item['item'],
'cate_detail' => getItems($item['cate']['date'], $item['item']['code'])
);
$filter_data[] = $data;
}
}
function getItems($date, $code) {
global $items;
$data = array();
foreach($items as $detail) {
if ($detail['cate']['date'] == $date && $detail['item']['code'] == $code) {
$data[] = array(
'rel_data_category' => $detail['cate_detail']['rel_data_category'],
'price' => $detail['cate_item']['price']
);
}
}
return $data;
}
pr($filter_data);
Demo

PHP assign one array value to another array

array (
0 =>
array (
'label' => '1',
'index' => 1,
'product_attributes' =>
array (
0 =>
array (
'type' => 'product',
'id' => 1,
'label' => 'Size',
'placeholder' => 'Select Size',
'description' => '',
'defaultValue' =>
array (
'text' => 'Size32',
'price' => '22',
'isSelected' => false,
),
'choices' =>
array (
0 =>
array (
'text' => 'Size30',
'price' => '20',
'isSelected' => 'true',
),
1 =>
array (
'text' => 'Size32',
'price' => '22',
'isSelected' => false,
),
),
'conditionalLogic' => '',
),
1 =>
array (
'type' => 'product',
'id' => 2,
'label' => 'Color',
'placeholder' => 'Select Color',
'description' => 'DEsc',
'defaultValue' =>
array (
'text' => 'Black',
'price' => '5',
'isSelected' => 'false',
),
'choices' =>
array (
0 =>
array (
'text' => 'Black',
'price' => '5',
'isSelected' => 'false',
),
1 =>
array (
'text' => 'Green',
'price' => '6',
'isSelected' => 'false',
),
2 =>
array (
'text' => 'Blue',
'price' => '4',
'isSelected' => 'true',
),
3 =>
array (
'text' => 'White',
'price' => '1',
'isSelected' => 'false',
),
),
'conditionalLogic' => '',
),
2 =>
array (
'type' => 'product',
'id' => 3,
'label' => 'Fit',
'placeholder' => 'Select Fit',
'description' => 'Select Fit',
'defaultValue' =>
array (
),
'choices' =>
array (
0 =>
array (
'text' => 'Slim',
'price' => '2',
'isSelected' => false,
),
1 =>
array (
'text' => 'Regular',
'price' => '3',
'isSelected' => false,
),
2 =>
array (
'text' => 'Casual',
'price' => '5',
'isSelected' => false,
),
),
'conditionalLogic' => '',
),
),
'total_product_cost' => '$27.00',
'total_product_price' => '27.00',
'product_id' => '36',
),
1 =>
array (
'label' => 'label21',
'total_product_cost' => '$27.00',
'total_product_price' => '27.00',
'index' => 3,
'product_id' => '36',
'product_attributes' =>
array (
0 =>
array (
'type' => 'product',
'id' => 1,
'label' => 'Size',
'placeholder' => 'Select Size',
'description' => '',
'defaultValue' =>
array (
'text' => 'Size32',
'price' => '22',
'isSelected' => false,
),
'choices' =>
array (
0 =>
array (
'text' => 'Size30',
'price' => '20',
'isSelected' => 'true',
),
1 =>
array (
'text' => 'Size32',
'price' => '22',
'isSelected' => false,
),
),
'conditionalLogic' => '',
'conditionalLogic2' =>
array (
'actionType' => 'show',
'logicType' => 'all',
'checkbox' => true,
'rules' =>
array (
0 =>
array (
'fieldId' => 2,
'operator' => 'is',
'value' => 'Black',
),
),
),
),
1 =>
array (
'type' => 'product',
'id' => 2,
'label' => 'Color',
'placeholder' => 'Select Color',
'description' => 'DEsc',
'defaultValue' =>
array (
'text' => 'Black',
'price' => '5',
'isSelected' => 'false',
),
'choices' =>
array (
0 =>
array (
'text' => 'Black',
'price' => '5',
'isSelected' => 'false',
),
1 =>
array (
'text' => 'Green',
'price' => '6',
'isSelected' => 'false',
),
2 =>
array (
'text' => 'Blue',
'price' => '4',
'isSelected' => 'true',
),
3 =>
array (
'text' => 'White',
'price' => '1',
'isSelected' => 'false',
),
),
'conditionalLogic' => '',
),
2 =>
array (
'type' => 'product',
'id' => 3,
'label' => 'Fit',
'placeholder' => 'Select Fit',
'description' => 'Select Fit',
'defaultValue' =>
array (
),
'choices' =>
array (
0 =>
array (
'text' => 'Slim',
'price' => '2',
'isSelected' => false,
),
1 =>
array (
'text' => 'Regular',
'price' => '3',
'isSelected' => false,
),
2 =>
array (
'text' => 'Casual',
'price' => '5',
'isSelected' => false,
),
),
'conditionalLogic' => '',
),
),
),
)
I have posted my array value. This values are dynamic. Here is two array conditionalLogic and conditionalLogic2 I want to assign those array key conditionalLogic2 exist and value should be assign to conditionalLogic. After assign conditionalLogic values into the conditionalLogic2 remove that key from my array list.
Check I have tried this way but not working -
// $data['values'] array I have posted above
foreach ($data['values'] as $products) {
foreach ($products['product_attributes'] as $product_choices) {
if (!empty($product_choices['conditionalLogic2']) && $product_choices['conditionalLogic'] == '') {
$product_choices['conditionalLogic'] = $product_choices['conditionalLogic2'];
unset($product_choices['conditionalLogic2']);
}
}
}
var_export($data['values']); exit;
Please help me and give me any solution how to replace the array value into another array.
What is the shortcut way to solve this problem?
It is usually better to avoid nested loops:
foreach ($data as &$datum) {
if (!isset($datum['product_attributes'])) {
continue;
}
$datum['product_attributes'] = array_map(function ($productAttribute) {
if (
!empty($productAttribute['conditionalLogic2'])
&& empty($productAttribute['conditionalLogic'])
) {
$productAttribute['conditionalLogic'] = $productAttribute['conditionalLogic2'];
unset($productAttribute['conditionalLogic2']);
}
return $productAttribute;
}, $datum['product_attributes']);
}
Here I used array_map() function to assign new arrays directly.
Here is working example.
Your code is almost right, but you're acting a local variables in foreach loops. You should bind them to original array items as follows:
foreach ($data['values'] as & $products) {
foreach ($products['product_attributes'] as & $product_choices) {
if (!empty($product_choices['conditionalLogic2']) && $product_choices['conditionalLogic'] == '') {
$product_choices['conditionalLogic'] = $product_choices['conditionalLogic2'];
unset($product_choices['conditionalLogic2']);
}
}
}
unset($products);
unset($product_choices);
If there is the end of current function scope, both unset may be omitted. But you may remove references from an array explicitly to avoid undesired affects in some code below in the same scope. I.e. $products = 10; somewhere below crushes your last branch of an array.
#chinu You are actually assigning or changing the local variables where scope is limited within for loop only so in this case, we should use pass by reference.
See the following code, it will work:
foreach ($data['values'] as &$products) {
foreach ($products['product_attributes'] as &$product_choices) {
if (!empty($product_choices['conditionalLogic2']) && $product_choices['conditionalLogic'] == '') {
$product_choices['conditionalLogic'] = $product_choices['conditionalLogic

CakePHP 2.4.0 Recusion Inside of Contain in Paginator->settings Not Working

I'm having an issue with Paginator->settings. For some reason, recursive is not working. Any ideas? I've tried setting $this->Cheese->recursive = 2 and haven't had any luck.
$this->Cheese->recursive = 2;
$this->Paginator->settings = array(
'CheeseCheckin' => array(
'fields' => array('id','created','comment','location','rating','short_url_hash','foursquare_id'),
'conditions'=>array(
'CheeseCheckin.cheese_id' => $id
),
'contain' => array(
'Cheese'=>array(
'fields' => array('id','name','created','modified','attachment_id'),
'Attachment' => array(
'fields' => array('id','name','ext','path')
)
),
'CheeseProducer' => array(
'fields' => array('name','created', 'id','attachment_id')
),
'User' => array(
'fields' => $this->userFields,
'Attachment' => array(
'fields'=>array('id','name','ext','path')
),
'StateRegion' => array(
'fields'=>array('name','code')
),
'Country' => array(
'fields'=>array('name','code')
)
),
'Place' => array(
'fields'=>array('id','name')
),
'UserAttachment' => array(
'fields' => array('id','ext','name','path')
)
),
'page' => $page,
'order' => array('CheeseCheckin.created' => 'DESC'),
'limit' => $limit,
'recursive' => 2
)
);
debug($this->Paginator->paginate('CheeseCheckin'));
The results look like:
array(
(int) 0 => array(
'CheeseCheckin' => array(
'id' => '62',
'created' => '2013-09-06 13:34:44',
'comment' => 'This is a test',
'location' => null,
'rating' => '4',
'short_url_hash' => '18ARMkq',
'foursquare_id' => '40d77680f964a5205d011fe3'
),
'UserAttachment' => array(
'id' => null,
'ext' => null,
'name' => null,
'path' => null
),
'User' => array(
'id' => '1',
'username' => '...',
'name' => 'Rob',
'profile_image_url' => '...',
'active' => '1',
'email' => 'robksawyer#gmail.com',
'private' => false,
'attachment_id' => '616',
'country_id' => '228',
'state_region_id' => '48'
),
'Cheese' => array(
'id' => '379',
'name' => 'Party In a Jar',
'created' => '2012-10-05 16:57:04',
'modified' => '2013-09-13 02:12:27',
'attachment_id' => '460'
),
'CheeseProducer' => array(
'name' => 'Alsea Acre Goat Cheese',
'created' => '2012-10-05 16:50:51',
'id' => '43',
'attachment_id' => null
),
'Place' => array(
'id' => null,
'name' => null
)
)
)
Fixed the issue. I just had to add user_id, attachment_id, etc. to the fields array.

rearrange multidimensional array in cakephp 2.2

I have this multidimensional assoc $modules array in cakephp 2.2.3:
array(
'type1' => array(
(int) 0 => array(
'name' => 'name16',
'type' => '1',
'category' => 'categoryC',
'zone' => 'zone1'
),
(int) 1 => array(
'name' => 'name17',
'type' => '1',
'category' => 'categoryB',
'zone' => 'zone1'
),
(int) 2 => array(
'name' => 'name18',
'type' => '1',
'category' => 'categoryA',
'zone' => 'zone3'
),
(int) 3 => array(
'name' => 'name19',
'type' => '1',
'category' => 'categoryC',
'zone' => 'zone3'
),
(int) 4 => array(
'name' => 'name22',
'type' => '1',
'category' => 'categoryA',
'zone' => 'zone2'
)
),
'type2' => array(
(int) 0 => array(
'name' => 'name1',
'type' => '2',
'category' => 'categoryB',
'zone' => 'zone2'
),
(int) 1 => array(
'name' => 'name2',
'type' => '2',
'category' => 'categoryB',
'zone' => 'zone2'
),
(int) 2 => array(
'name' => 'name3',
'type' => '2',
'category' => 'categoryA',
'zone' => 'zone1'
),
(int) 3 => array(
'name' => 'name4',
'type' => '2',
'category' => 'categoryC',
'zone' => 'zone3'
),
(int) 4 => array(
'name' => 'name5',
'type' => '2',
'category' => 'categoryA',
'zone' => 'zone3'
)
)
)
and I want to rearrange it like
array(
'zone1' => array(
'type1' => array(
(int) 0 => array(
'name' => 'name17',
'type' => '1',
'category' => 'categoryB'
),
(int) 1 => array(
'name' => 'name16',
'type' => '1',
'category' => 'categoryC'
)
),
'type2' => array(
(int) 0 => array(
'name' => 'name3',
'type' => '2',
'category' => 'categoryA'
)
)
),
'zone2' => array(
'type1' => array(
(int) 0 => array(
'name' => 'name22',
'type' => '1',
'category' => 'categoryA'
)
),
'type2' => array(
(int) 0 => array(
'name' => 'name1',
'type' => '2',
'category' => 'categoryB'
),
(int) 1 => array(
'name' => 'name2',
'type' => '2',
'category' => 'categoryB'
)
)
),
'zone3' => array(
'type1' => array(
(int) 0 => array(
'name' => 'name18',
'type' => '1',
'category' => 'categoryA'
),
(int) 0 => array(
'name' => 'name19',
'type' => '1',
'category' => 'categoryC'
)
),
'type2' => array(
(int) 0 => array(
'name' => 'name5',
'type' => '2',
'category' => 'categoryA'
),
(int) 1 => array(
'name' => 'name4',
'type' => '2',
'category' => 'categoryC'
)
)
)
)
where 'category' should be sorted alphabetically within each parent 'type'
I tried with
$modules = Hash::combine($modules, '{n}', '{n}.{n}', '{s}.{s}.{n}.zone');
but with no success. I guess I'm not using Hash::combine as I should...
Thanks, Marius
Just use a foreach inside a foreach to walk through your array and construct a new one based on your preference.

Categories