how to filter array using php? - php

print_r($menus); gives the following output:
Array
(
[0] => Array
(
[name] => Politics
[action] => politics
)
[sub_menu2] => Array
(
[0] => Array
(
[name] => submenu2
[action] => politics
)
[1] => Array
(
[name] => submenu3
[action] => sport
)
)
)
My expected filtered array is:
Array
(
[0] => Array
(
[name] => Politics
[action] => politics
[sub_menu2] => Array
(
[0] => Array
(
[name] => submenu2
[action] => politics
)
[1] => Array
(
[name] => submenu3
[action] => sport
)
)
)
)
My code is:
$filteredMenu = array();
$unique = array();
$index = 0;
$index2 = 0;
foreach ($menus as $key => $menu) {
$pm = $menu['Menu']['name'];
if (isset($unique[$pm])) {
if (!empty($menu['sub_menus']['name'])) {
$temp = array('name' => $menu['sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['sub_menu'][] = $temp;
}
if(!empty($menu['sub_sub_menus']['name'])){
$temp = array('name' => $menu['sub_sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['sub_menu']['sub_menu2'][] = $temp;
}
} else {
if ($key != 0)
$index++;
$unique[$pm] = 'set';
$temp = array('name' => $pm, 'action' => $menu['Menu']['action']);
$filteredMenu[$index]['menu'] = $temp;
if (!empty($menu['sub_menus']['name'])) {
$temp = array('name' => $menu['sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['sub_menu'][] = $temp;
}
if(!empty($menu['sub_sub_menus']['name'])){
$temp = array('name' => $menu['sub_sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['sub_menu']['sub_menu2'][] = $temp;
}
}
}
I can filter to wrap all sum menus under menu. But I can't wrap all second level sub menu under sub menu. I spent lot of time to solve but failed.

Your php code is different from your array. From where you find
$pm = $menu['Menu']['name'];
this will display error Undefined index: Menu
I think you have to apply more condition.
I don't sure apply below code. I think this will solve your problem.
$filteredMenu = array();
$unique = array();
$index = 0;
$index2 = 0;
foreach ($menus as $key => $menu) {
$pm = $menu['Menu']['name'];
$pm1 = $menu['sub_menus']['name'];
if (isset($unique[$pm])) {
if (!empty($menu['sub_menus']['name'])) {
$temp = array('name' => $menu['sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['menu']['sub_menu'][] = $temp;
}
if(!empty($menu['sub_sub_menus']['name'])){
$temp = array('name' => $menu['sub_sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['menu']['sub_menu']['sub_menu2'][] = $temp;
}
} else {
if ($key != 0)
$index++;
$unique[$pm] = 'set';
$temp = array('name' => $pm, 'action' => $menu['Menu']['action']);
$filteredMenu[$index]['menu'] = $temp;
if (!empty($menu['sub_menus']['name'])) {
$temp = array('name' => $menu['sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['menu']['sub_menu'][] = $temp;
}
if(!empty($menu['sub_sub_menus']['name'])){
$temp = array('name' => $menu['sub_sub_menus']['name'], 'action' => $menu['sub_menus']['action']);
$filteredMenu[$index]['menu']['sub_menu']['sub_menu2'][] = $temp;
}
}
}

Related

Remove key in multidimensional array

I want to delete key [Price] but the function which I use for deletion doesn't work for this case
I have:
Array(
[Values] => 1
[Product] => Array(
[Details] => Array(
[ID] => 1
[Price] => Array(
)
)
)
)
My goal is:
Array(
[Values] => 1
[Product] => Array(
[Details] => Array(
[ID] => 1
)
)
)
I use this for removal:
function remove_key($array, $key)
{
foreach($array as $k => $v) {
if(is_array($v)) {
$array[$k] = remove_key($v, $key);
} elseif($k == $key) {
unset($array[$k]);
}
}
return $array;
}
$array = remove_key($array,'Price');
What is wrong here?
<?php
$array = Array(
'Values' => 1,
'Product' => Array(
'Details' => Array(
'id' => 1,
'Price' => Array(
)
)
)
);
unset($array['Product']['Details']['Price']);
echo "<pre>";
print_r($array);
echo "</pre>";
And the output is :
Array
(
[Values] => 1
[Product] => Array
(
[Details] => Array
(
[id] => 1
)
)
)
so if you want to fix your function you must add another condition into first if as so && $k != $key
because you are not getting into elseif and unset is not called
function remove_key($array, $key)
{
foreach($array as $k => $v) {
if(is_array($v) && $k != $key) {
$array[$k] = remove_key($v, $key);
} elseif($k == $key) {
unset($array[$k]);
}
}
return $array;
}

How to create sub arrays with help of parent id

Here is my collected array.
$raw_ar = Array (
0 => Array ( 'ID' => 6, 'pageTitle' => 'First', 'pageContent' => 'http://localhost/cms/1', 'parentID' => 0 ),
1 => Array ( 'ID' => 7, 'pageTitle' => 'Second', 'pageContent' => 'http://localhost/cms/2', 'parentID' => 6 ),
2 => Array ( 'ID' => 8, 'pageTitle' => 'Third', 'pageContent' => 'http://localhost/cms/3', 'parentID' => 6 ) ,
3 => Array ( 'ID' => 9, 'pageTitle' => 'Four', 'pageContent' => 'http://localhost/cms/4', 'parentID' => 0 )
) ;
And my result should be like this
$final_ar = array(
0 => array ( 'ID' => 6, 'pageTitle' => 'First', 'pageContent' => 'http://localhost/cms/1', 'parentID' => 0 ,
'sub_items' => array(
0 => array('ID' => 7, 'pageTitle' =>'second', 'pageContent' => 'http://localhost/cms/2', 'parentID' => 6),
1 => array('ID' => 8, 'pageTitle' => 'Third', 'pageContent' => 'http://localhost/cms/3', 'parentID' => 6),
)
),
1 => array('ID' => 9, 'pageTitle' => 'Four', 'pageContent' => 'http://localhost/cms/4', 'parentID' => 0)
);
And here is my code
$final_ar = array();
foreach ($raw_ar as $value) {
if($value['parentID'] ==0){
$final_ar[] = $value;
}
else{
$pID = $value['parentID'];
foreach ($final_ar as $value1) {
//echo $value1['ID'].'-'.$pID;
if($value1['ID'] == $pID){
//if(isset($value1['sub_items'])){
$value1['sub_items'][] = $value;
//}else
//$value1['sub_items'] = $value;
}
$temp_ar[] = $value1;
}
$exist = 0;
foreach ($final_ar as $key => $val) {
# code...
if($val['ID'] == $temp_ar['ID']){
unset($final_ar[$key]);
$final_ar[$key] = $temp_ar;
$exist =1;
break;
}
}
if($exist == 0)
$final_arr[] = $temp_ar;
//$parent_key = array_column($raw_ar,'ID', 'parentID');
}
}
print_r($final_arr);
And I tried to code it with sub_items . But it helps to create array. But I don't know how to remove existing array once it modifies. It gives the result like this.
Array ( [0] => Array ( [0] => Array ( [ID] => 6 [pageTitle] => First [pageContent] => http://localhost/cms/1 [parentID] => 0 [sub_items] => Array ( [0] => Array ( [ID] => 7 [pageTitle] => Second [pageContent] => http://localhost/cms/2 [parentID] => 6 ) ) ) ) [1] => Array ( [0] => Array ( [ID] => 6 [pageTitle] => First [pageContent] => http://localhost/cms/1 [parentID] => 0 [sub_items] => Array ( [0] => Array ( [ID] => 7 [pageTitle] => Second [pageContent] => http://localhost/cms/2 [parentID] => 6 ) ) ) [1] => Array ( [ID] => 6 [pageTitle] => First [pageContent] => http://localhost/cms/1 [parentID] => 0 [sub_items] => Array ( [0] => Array ( [ID] => 8 [pageTitle] => Third [pageContent] => http://localhost/cms/3 [parentID] => 6 ) ) ) ) )
Try this:
function formatArray($nonFormattedArray) {
$formattedArray = [];
$subItems = [];
foreach ($nonFormattedArray as $item) {
$pid = $item['parentID'];
if ($pid != 0) {
if (isset($subItems[$pid]))
$subItems[$pid][] = $item;
else
$subItems[$pid] = [$item];
} else
$formattedArray[] = $item;
}
foreach ($formattedArray as $key => $parent) {
resolveChild($formattedArray[$key], $subItems);
}
return $formattedArray;
}
function resolveChild(&$parent, &$subItems) {
//return if no child
if (!isset($subItems[$parent['ID']]))
return $parent;
foreach ($subItems[$parent['ID']] as $key => $child) {
if (isset($parent['sub_items']))
$parent['sub_items'][] = resolveChild($subItems[$parent['ID']][$key], $subItems);
else
$parent['sub_items'] = [resolveChild($subItems[$parent['ID']][$key], $subItems)];
}
return $parent;
}
Now, formatArray($nonFormattedArray) should return your desired answer.
This will be independent of the order of your parent and child items and will reduce the total iteration count and execution time.
This will produce an Array as deep as the inheritance in the data.
Note that execution time will increase with the increment in inheritance level.
So many code you have here.
Here's my version:
foreach ($raw_ar as $value) {
if ($value['parentID'] == 0) {
$final_ar[$value['ID']] = $value;
}
}
foreach ($raw_ar as $value) {
$parent_id = $value['parentID'];
if (0 < $parent_id) {
if (!isset($final_ar[$parent_id]['sub_items'])) {
$final_ar[$parent_id]['sub_items'] = [];
}
$final_ar[$parent_id]['sub_items'][] = $value;
}
}
$final_ar = array_values($final_ar); // if you need 0-indexed array
If you're 100% sure that parent items in your array come before child ones - you can join both foreaches into one:
foreach ($raw_ar as $value) {
$parent_id = $value['parentID'];
if ($parent_id == 0) {
$final_ar[$value['ID']] = $value;
} else {
if (!isset($final_ar[$parent_id]['sub_items'])) {
$final_ar[$parent_id]['sub_items'] = [];
}
$final_ar[$parent_id]['sub_items'][] = $value;
}
}
$final_ar = array_values($final_ar); // if you need 0-indexed array

Re-arrange array (move from key to value) and organize order

I have this array:
Array
(
[LLLLLLL:] => Array
(
[ brand1:] => Array
(
[people: (100%)] => Array
(
)
[countries: (90%)] => Array
(
)
[yyyy: (80%)] => Array
(
)
[languages: (70%)] => Array
(
)
)
[ brand2:] => Array
(
[people: (60%)] => Array
(
)
[countries: (50%)] => Array
(
)
[yyyy: (40%)] => Array
(
)
[languages: (30%)] => Array
(
)
)
)
)
How can I re-arrange my array in order to have this:
array(
array(
('LLLLLLL') => 'people',
('BRAND1') => '100%',
('BRAND2') => '60%'),
array(
('LLLLLLL') => 'countries',
('BRAND1') => '90%',
('BRAND2') => '50%')
array(
('LLLLLLL') => 'yyyy',
('BRAND1') => '80%',
('BRAND2') => '50%')
array(
('LLLLLLL') => 'languages',
('BRAND1') => '70%',
('BRAND2') => '30%',
I have no idea, how to, for example, move the string after ':' on key to the value and than re-arrange in the different order. How can this be done?
I think this should do it. Please note that it was not tested:
$result = array();
foreach ($initialArray as $lll => $brands) {
$lll = rtrim($lll, ':');
foreach ($brands as $brandName => $brandValues) {
$brandName = strtoupper(preg_replace('/[\s:]/', '', $brandName));
$values = array_keys($brandValues);
foreach ($values as $value) {
preg_match('/([a-z]*): \(([0-9]*%)\)/', $value, $matches);
if (!isset($result[$matches[1]])) {
$result[$matches[1]] = array($lll => $matches[1]);
}
$result[$matches[1]][$brandName] = $matches[2];
}
}
}
You can use regexp + array_map for it.
$datos = Array(
'LLLLLLL:' => Array(
'brand1:' => Array(
'people: (100%)' => Array
(
),
'countries: (90%)' => Array
(
),
'yyyy: (80%)' => Array
(
),
'languages: (70%)' => Array
(
)
),
'brand2:' => Array(
'people: (60%)' => Array
(
),
'countries: (50%)' => Array
(
),
'yyyy: (40%)' => Array
(
),
'languages: (30%)' => Array
(
)
)
)
);
$datos = array_map(function($row) {
$ret = array();
foreach ($row as $key => $items) {
foreach ($items as $dato => $vacio) {
if (preg_match('/([^:]+): \(([^\)]+)\)/i', $dato, $coincidencias)) {
$pos = $coincidencias[1];
if (!isset($ret[$pos]))
$ret[$pos] = array();
$ret[$pos][$key] = $coincidencias[2];
}
}
}
return $ret;
}, $datos);
echo '<pre>' . print_r($datos, true);
Is not completed, but you can go in this way.

find all duplicates values in multi dimensional array php

I have a array as following
array(
0 => array('email' => 'abc#abc.com','name'=>'abc'),
1 => array('email' => 'xyz#abc.com','name'=>'xyz'),
2 => array('email' => 'uvw#abc.com','name'=>'uvw'),
3 => array('email' => 'abc#abc.com','name'=>'str'),
)
I want to filter out records on email address and get records having same email address. For example from above example I want
array(
0 => array(
array(
0 => array('email' => 'abc#abc.com','name'=>'abc'),
1 => array('email' => 'abc#abc.com','name'=>'str'),
)
)
My code is
$tmpArray = array();
$duplicateRecords = array();
if (empty($data)) {
return false;
}
foreach ($data as $key => $value) {
if (in_array($value['Email'], $tmpArray)) {
$duplicateRecords[] = $value;
}
$tmpArray[] = $value['Email'];
}
echo '<pre>';print_r($duplicateRecords);die;
But this piece of code only returns the record's once existance, which is of second time. I know when It is traversing first time it isn't having email to compare. Is there any way to get existence of record as many times as it is in array.
// get count of each email
$counters = array_count_values(array_column($data, 'email'));
// collect email with counter > 1
$result = [];
foreach ($data as $item) {
if ($counters[$item['email']] > 1) {
$result[] = $item;
}
}
This one should work for you:
foreach($array as $key => $value) {
foreach ($array as $k => $v) {
if ($key < $k && $value['email'] == $v['email']) {
$result[] = array(
$value,
$v
);
}
}
}
PHPFiddle Link: http://phpfiddle.org/main/code/8trq-k2zc
Please note: this would only find you the conflicting pairs. For example:
$array = array(
array(
'email' => 'abc#abc.com',
'name' => 'abc'
),
array(
'email' => 'abc#abc.com',
'name' => 'def'
),
array(
'email' => 'abc#abc.com',
'name' => 'ghi'
)
);
Would result in:
Array
(
[0] => Array
(
[0] => Array
(
[email] => abc#abc.com
[name] => abc
)
[1] => Array
(
[email] => abc#abc.com
[name] => def
)
)
[1] => Array
(
[0] => Array
(
[email] => abc#abc.com
[name] => abc
)
[1] => Array
(
[email] => abc#abc.com
[name] => ghi
)
)
[2] => Array
(
[0] => Array
(
[email] => abc#abc.com
[name] => def
)
[1] => Array
(
[email] => abc#abc.com
[name] => ghi
)
)
)
So abc conflicts with def, abc conflicts with ghi, and def conflicts with ghi.
This is a 'two pass' solution. The code is commented.
PHP 5.3.18
<?php // https://stackoverflow.com/questions/26548634/find-all-duplicates-values-in-multi-dimensional-array-php
$data = array(
0 => array('email' => 'abc#abc.com','name'=>'abc'),
1 => array('email' => 'xyz#abc.com','name'=>'xyz'),
2 => array('email' => 'uvw#abc.com','name'=>'uvw'),
3 => array('email' => 'abc#abc.com','name'=>'str'),
);
// two passes required
// first pass: count of emails
$emailCounts = array();
foreach($data as $emailEntry) {
if (isset($emailCounts[$emailEntry['email']])) {
$emailCounts[$emailEntry['email']] += 1;
}
else {
$emailCounts[$emailEntry['email']] = 1;
}
}
// second pass: extract duplicate emails (count > 1)
$duplicateEmails = array();
foreach($data as $emailEntry) {
if ($emailCounts[$emailEntry['email']] > 1) {
$duplicateEmails[] = $emailEntry;
}
}
// show output...
var_dump($emailCounts);
var_dump($duplicateEmails);
Actual output:
array
'abc#abc.com' => int 2
'xyz#abc.com' => int 1
'uvw#abc.com' => int 1
array
0 =>
array
'email' => string 'abc#abc.com' (length=11)
'name' => string 'abc' (length=3)
1 =>
array
'email' => string 'abc#abc.com' (length=11)
'name' => string 'str' (length=3)
Here is the code for you
>$mainarray=array(
0 => array('email' => 'abc#abc.com','name'=>'abc'),
1 => array('email' => 'xyz#abc.com','name'=>'xyz'),
2 => array('email' => 'uvw#abc.com','name'=>'uvw'),
3 => array('email' => 'abc#abc.com','name'=>'str'),
);
foreach($mainarray as $single){
$emailarray[]=$single['email'];
}
foreach(array_count_values($emailarray) as $val => $c)
if($c > 1) $dups[] = $val;
foreach($mainarray as $single){
if(in_array($single['email'], $dups)){
$result[]=$single;
}
}
echo '<pre>';print_r($result);

How can I replace a certain part of array using PHP?

Just need a little help here about arrays. Because I am trying to create a code that when you click it it will replace a certain array values.
In the base array suppose that we have this array:
Array(
[0] => Array(
[id] => 1,
[name] => xyz
),
[1] => Array(
[id] => 4,
[name] => fsa
),
)
And in my new array I have something like this
Array(
[id] => 4,
[name] => pop
)
I have a validation like this: In the base array I put this array in $base_array and in my new array I have $update_array
$get_updated_array_id = $update_array[id];
for($x = 0; $x <= sizeof($base_array); $x++){
$target = $base_array[$x]['id'];
if($get_updated_array_id == $target){
//should be replace the array value ID '4'
}
}
So the final result should be:
Array(
[0] => Array(
[id] => 1,
[name] => xyz
),
[1] => Array(
[id] => 4,
[name] => pop
),
)
Any idea how can I do that? Thanks
<?php
$array = array(
array('id' => 2,'name' => 'T'),
array('id' => 4,'name' => 'S')
);
$replace = array('id' => 4,'name' => 'New name');
foreach ($array as $key => &$value) {
if($value['id'] == $replace['id'] ) {
$value = $replace;
}
}
print_r($array);
$new_array = array(
[id] => 4,
[name] => pop
);
$get_updated_array_id = $update_array[id];
for($x = 0; $x <= sizeof($base_array); $x++){
$target = $base_array[$x]['id'];
if($get_updated_array_id == $target){
$base_array[$x] = $new_array;
}
}
//PHP >= 5.3
array_walk($base_array, function (& $target) use ($update_array) {
if ($target['id'] == $update_array['id']) {
$target = $update_array;
}
});

Categories