I want to remove duplicates where either measurement or altunit matches another array, but ignoring if they're blank.
Array
(
[0] => Array
(
[id] => 2
[altunit] => %
[measurement] =>
)
[1] => Array
(
[id] => 3
[altunit] =>
[measurement] => 6
)
[2] => Array
(
[id] => 4
[altunit] => %
[measurement] =>
)
[3] => Array
(
[id] => 5
[altunit] =>
[measurement] => 6
)
[4] => Array
(
[id] => 6
[altunit] =>
[measurement] => 6
)
)
Becomes
Array
(
[0] => Array
(
[id] => 2
[altunit] => %
[measurement] =>
)
[1] => Array
(
[id] => 3
[altunit] =>
[measurement] => 6
)
)
Best I can come up with is:
$test = array ( 0 => array ( 'id' => '2', 'altunit' => '%', 'measurement' => NULL, ), 1 => array ( 'id' => '3', 'altunit' => NULL, 'measurement' => '6', ), 2 => array ( 'id' => '4', 'altunit' => NULL, 'measurement' => '6', ), 3 => array ( 'id' => '5', 'altunit' => NULL, 'measurement' => '6', ), 4 => array ( 'id' => '6', 'altunit' => NULL, 'measurement' => '6', ), );
$num = [];
foreach($test as $k => $v) $num[] = $v['measurement'];
But this only works for measurement, and removes the id and altunit keys.
Humm,
Make an array of 'knowed value' for measurement and altunit and then check it it exist on the rest of the values.
something like:
$knowed_altunit=array();
$knowed_measurement=array();
foreach($test as $k=>$v){
if(in_array($v['altunit'],$knowed_altunit)
|| in_array($v['mesurement'],$knowed_measurement)){
//if the value of altunit or measurement is already knowed then remove the entry from the array,
unset($test[$k]);
}else{
//if it never been seen, add it so further entry can be checked agaisnt the knowed value
$knowed_altunit[]=$v['altunit'];
$knowed_measurement[]=$v['mesurement'];
}
}
Sorry if any typo but thins might help you wrap your head around the solution to your problem.
You can try this code:
<?php
/* before you need to check that $test variable is declarated and have all items to check */
$values_altunit = array();
$values_measurement = array();
$result = array();
foreach($test as $key => $value) {
/* check if exist altunit and measurement values in blacklist arrays */
if (!in_array($value['altunit'], $values_altunit) && !in_array($value['measurement'], $values_measurement)) {
/* if not exist, add the item to $result array */
$result[$key] = $value;
/* and add altunit and measurement values to blacklist arrays */
$values_altunit[] = $value['altunit'];
$values_measurement[] = $value['measurement'];
}
}
/* print result items */
var_dump($result);
?>
This is a short code that can give the result for unique measurements
<?php
$arr = array(
"0"=> array (
"id" => 2,
"altunit" => "%",
"measurement" => "",
),
"1"=> array (
"id" => 3,
"altunit" => "",
"measurement" => 6,
),
"2"=> array (
"id" => 4,
"altunit" => "%",
"measurement" => "",
),
"3"=> array (
"id" => 5,
"altunit" => "",
"measurement" => 6,
),
"4"=> array (
"id" => 6,
"altunit" => "",
"measurement" => 6,
)
);
$unique_measure = $new_array = array();
foreach($arr as $sup_key => $sup_val){
foreach($sup_val as $sub_key => $sub_val){
if(!in_array($sup_val['measurement'], $unique_measure)){
array_push($unique_measure, $sup_val['measurement']);
array_push($new_array,$sup_val);
}
}
}
print_r($new_array);
?>
Output :
Array
(
[0] => Array
(
[id] => 2
[altunit] => %
[measurement] =>
)
[1] => Array
(
[id] => 3
[altunit] =>
[measurement] => 6
)
)
try this code. it may do the trick.
One More approach to your problems solution can be removing that particular key from the main array using unset(your_array_key) will do the trick in the same code.
Try, this may help you
function remove_dup($array, $keys )
{
$out = array();
foreach($array as $sub)
{
if(empty($out))
{
$out[] = $sub;
continue;
}
foreach($keys as $key)
{
if($flag=in_array( $sub[$key],array_map(function($e) use($key){ return $e[$key];}, $out)) )
break;
}
if(!$flag)
$out[] = $sub;
}
return $out;
}
// Usage
print_r( remove_dup($array, array('altunit','measurement') ) );
Test
[akshay#localhost tmp]$ cat test.php
<?php
function remove_dup($array, $keys )
{
$out = array();
foreach($array as $sub)
{
if(empty($out))
{
$out[] = $sub;
continue;
}
foreach($keys as $key)
{
if($flag=in_array( $sub[$key],array_map(function($e) use($key){ return $e[$key];}, $out)) )
break;
}
if(!$flag)
$out[] = $sub;
}
return $out;
}
$array = array(
"0"=> array (
"id" => 2,
"altunit" => "%",
"measurement" => "",
),
"1"=> array (
"id" => 3,
"altunit" => "",
"measurement" => 6,
),
"2"=> array (
"id" => 4,
"altunit" => "%",
"measurement" => "",
),
"3"=> array (
"id" => 5,
"altunit" => "",
"measurement" => 4,
),
"4"=> array (
"id" => 6,
"altunit" => "",
"measurement" => 6,
)
);
print_r( remove_dup($array, array('altunit','measurement') ) );
?>
Output
[akshay#localhost tmp]$ php test.php
Array
(
[0] => Array
(
[id] => 2
[altunit] => %
[measurement] =>
)
[1] => Array
(
[id] => 3
[altunit] =>
[measurement] => 6
)
)
What you really want is a set, not an array. So if you can't fix the way you're building the array in the first place (my guess is this came from an SQL query, which would be a lot less code to rectify) you have two options for creating mapped sets in PHP.
You could use SplObjectStorage
You could use an Array with the key as a serialized representation of the set
The first approach would look something like this...
$set = new SplObjectStorage();
$arr = [
0 => [
'id' => '2',
'altunit' => '%',
'measurement' => NULL,
],
1 => [
'id' => '3',
'altunit' => NULL,
'measurement' => '6',
],
2 => [
'id' => '4',
'altunit' => NULL,
'measurement' => '6',
],
3 => [
'id' => '5',
'altunit' => NULL,
'measurement' => '6',
],
4 => [
'id' => '6',
'altunit' => NULL,
'measurement' => '6',
],
];
foreach($arr as $part) {
if (isset($part['altunit'])) { // ignore if blank
$key = (object) $part;
$set->attach($key); // attach the set
}
}
// Now you have...
foreach($set as $value) {
var_dump($value);
}
This would give you...
object(stdClass)#2 (3) {
["id"]=>
string(1) "2"
["altunit"]=>
string(1) "%"
["measurement"]=>
NULL
}
The second approach, using an array, where the array key represents a serialized version of the set would look something like this...
$set = [];
$arr = [
0 => [
'id' => '2',
'altunit' => '%',
'measurement' => NULL,
],
1 => [
'id' => '3',
'altunit' => NULL,
'measurement' => '6',
],
2 => [
'id' => '4',
'altunit' => NULL,
'measurement' => '6',
],
3 => [
'id' => '5',
'altunit' => NULL,
'measurement' => '6',
],
4 => [
'id' => '6',
'altunit' => NULL,
'measurement' => '6',
],
];
foreach($arr as $part) {
if (isset($part['altunit'])) { // ignore if blank
$key = "{$part['altunit']}\0{$part['measurement']}";
$set[$key] = $part; // attach the set
}
}
// Now you have...
foreach($set as $value) {
var_dump($value);
}
And that would give you...
array(3) {
["id"]=>
string(1) "2"
["altunit"]=>
string(1) "%"
["measurement"]=>
NULL
}
N.B
But, if this is a result set from an SQL query it's quite possible you could just more effectively eliminate the de-duplication process entirely by modifying the query to use WHERE NOT NULL and GROUP BY clauses instead.
You can try this also
<?php
$keys = array_map(function ($i) { return $i; }, $array);
$dumparr = array_combine($keys, $array);
$result = array_values($deduped);
print_r($result);
?>
Related
How to remove some keys from an array inside another array in PHP?
I have this structure:
array (
0 =>
array (
'num' => '123',
'nome' => 'test 001'
'pontos' => 68,
'data_status' => '03/09/2021 10:05',
'uuid_status' => '69450ea451ae11ea85ca309c23d3a0ed'
),
1 =>
array (
'num' => '345',
'nome' => 'test 002'
'pontos' => 120,
'data_status' => '27/08/2021 15:46',
'uuid_status' => '3cbf4fd15d5411ea86956eef5d66cb13',
),
)
and need to return something like this:
array (
0 =>
array (
'num' => '123',
'nome' => 'test 001'
'pontos' => 68
),
1 =>
array (
'num' => '345',
'nome' => 'test 002'
'pontos' => 120
)
)
I've seen some answers but they seem to be outdated, also i'm using Laravel, so it would help if someone point me out something from the framework and its equivalent in pure PHP
A simple foreach loop is a good starting point, note this will remove items from the original array, by using the reference & to the array rather than a normal simple copy. On the $val in the foreach ( $input as &$val){
$input = [
[
'num' => '123',
'nome' => 'test 001',
'pontos' => 68,
'data_status' => '03/09/2021 10:05',
'uuid_status' => '69450ea451ae11ea85ca309c23d3a0ed'
],[
'num' => '345',
'nome' => 'test 002',
'pontos' => 120,
'data_status' => '27/08/2021 15:46',
'uuid_status' => '3cbf4fd15d5411ea86956eef5d66cb13'
]
];
$remove = ['data_status','uuid_status'];
foreach ( $input as &$val){
foreach ($val as $k => $v) {
if ( in_array($k,$remove) ) {
unset( $val[$k]);
}
}
}
print_r($input);
RESULT
Array
(
[0] => Array
(
[num] => 123
[nome] => test 001
[pontos] => 68
)
[1] => Array
(
[num] => 345
[nome] => test 002
[pontos] => 120
)
)
Probably not the most concise, but it gets the job done:
$bad_keys = array('data_status', 'uuid_status');
$array = array (
0 =>
array (
'num' => '123',
'nome' => 'test 001',
'pontos' => 68,
'data_status' => '03/09/2021 10:05',
'uuid_status' => '69450ea451ae11ea85ca309c23d3a0ed',
),
1 =>
array (
'num' => '345',
'nome' => 'test 002',
'pontos' => 120,
'data_status' => '27/08/2021 15:46',
'uuid_status' => '3cbf4fd15d5411ea86956eef5d66cb13',
),
);
function traverse_array($array, $bad_keys) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = traverse_array($value, $bad_keys);
} else {
foreach ($bad_keys as $remove_me) {
if ($key == $remove_me) {
unset($array[$key]);
}
}
}
}
return $array;
}
print_r(traverse_array($array, $bad_keys));
I have 2 arrays of arrays which I want to merge by keys for the first step and them sum on the second step - example:
Array
(
[2017-03-01] => Array
(
[apples] => 2
[bananas] => 1
)
[2017-03-02] => Array
(
[apples] => 3
[bananas] => 6
)
[2017-03-03] => Array
(
[apples] => 0
[bananas] => 4
)
}
Array
(
[2017-03-01] => Array
(
[apples] => 3
[bananas] => 2
)
[2017-03-02] => Array
(
[apples] => 4
[bananas] => 7
)
[2017-03-03] => Array
(
[apples] => 1
[bananas] => 5
)
}
Wanted result:
Array
(
[2017-03-01] => Array
(
[apples] => 5
[bananas] => 3
)
[2017-03-02] => Array
(
[apples] => 7
[bananas] => 13
)
[2017-03-03] => Array
(
[apples] => 1
[bananas] => 9
)
}
Is there a command that does that (as a 1 single command) that will avoid looping through the arrays?
No. (obligatory additional characters)
Here's an insanely inefficient way of doing but without using any sort of for foreach or while
$result = array_map(function ($aentry, $key) use ($b) {
$bentry = $b[$key] ?? [];
$result = array_map(function ($value, $key) use ($bentry) {
return [$key, $value + ($bentry[$key] ?? 0) ];
},$aentry, array_keys($aentry));
return [ $key, array_combine(array_column($result, 0), array_column($result, 1)) ];
}, $a,array_keys($a));
$result = array_combine(array_column($result, 0), array_column($result, 1));
Example: http://sandbox.onlinephpfunctions.com/code/4c1dca3057c33dd17d0106666a497c7b08e57038
Solution without for/foreach/... , assuming that all keys are the same, you can do:
$array1 = [
'2017-03-01' => [
'apples' => 2,
'bananas' => 1,
],
'2017-03-02' => [
'apples' => 3,
'bananas' => 6,
],
'2017-03-03' => [
'apples' => 0,
'bananas' => 4,
],
];
$array2 = [
'2017-03-01' => [
'apples' => 3,
'bananas' => 2,
],
'2017-03-02' => [
'apples' => 4,
'bananas' => 7,
],
'2017-03-03' => [
'apples' => 1,
'bananas' => 5,
],
];
array_walk($array1, function(&$subarray1, $key) use($array2) {
array_walk($subarray1, function(&$element, $subkey) use($array2, $key) {
$element += $array2[$key][$subkey];
});
});
Not good performance, just for fun.
Thank you all for your answers, here is my code:
function merge_fruit_data($new_data, $old_data){
// If it's the first time running - return new data as an array
if (empty($old_data)){
return $new_data;
}
else {
foreach ( $new_data as $key => $insert_new_data ) {
if ( !$old_data[$key] ) {
$old_data[$key] = $insert_new_data;
}
else{
$old_data[$key]['apples'] += $insert_new_data['apples'];
$old_data[$key]['bananas'] += $insert_new_data['bananas'];
}
}
}
return $old_data;
}
Efficiency comments are welcome.
This may help you
`$a = array('2017-03-01' => array('apples'=> 2, 'bananas'=>1),
'2017-03-02' => array('apples'=> 3, 'bananas'=>6),
'2017-03-03' => array('apples'=> 0, 'bananas'=>4));
$b=array('2017-03-01' => array('apples'=> 3, 'bananas'=>2),
'2017-03-02' => array('apples'=> 4, 'bananas'=>7),
'2017-03-03' => array('apples'=> 1, 'bananas'=>5));
$sumArray = array();
foreach ($a as $key=>$value) {
$sumArray[$key]['apples']=($a[$key]['apples']+$b[$key]['apples']);
$sumArray[$key]['bananas']=($a[$key]['bananas']+$b[$key]['bananas']);
}
print_r($sumArray);
`
$sortMod = [
[
'group_id' => 1,
'group_name'=>'Home',
'module_id' => 1,
'mod_name' => 'Home',
'mod_link' => '/home',
'var_name' => 'home'
], [
'group_id'=> 2,
'module_id' => 2,
'mod_name' => 'Numbers',
'mod_link' => '/number_mapping',
'var_name' => 'numbermap'
], [
'group_id'=> 2,
'module_id' => 70,
'mod_name' => 'DR Plan',
'mod_link' => '/dr_plan',
'var_name' => 'dr_plan'
], [
'group_id'=> 3,
'module_id' => 8,
'mod_name' => 'Reporting',
'mod_link' => '/reporting',
'var_name' => 'reporting'
], [
'group_id'=> 3,
'module_id' => 80,
'mod_name' => 'Scheduler',
'mod_link' => '/scheduler',
'var_name' => 'scheduler'
]
];
I want to group the result by group_id;
$sortMod = [
[
'group_id' => 1,
'group_name'=>'Home',
'module_id' => 1,
'mod_name' => 'Home',
'mod_link' => '/home',
'var_name' => 'home'
], [
'group_id'=> 2,
[
'module_id' => 2,
'mod_name' => 'Numbers',
'mod_link' => '/number_mapping',
'var_name' => 'numbermap'
], [
'module_id' => 70,
'mod_name' => 'DR Plan',
'mod_link' => '/dr_plan',
'var_name' => 'dr_plan'
]
], [
'group_id'=> 3,
[
'module_id' => 8,
'mod_name' => 'Reporting',
'mod_link' => '/reporting',
'var_name' => 'reporting'
], [
'module_id' => 80,
'mod_name' => 'Scheduler',
'mod_link' => '/scheduler',
'var_name' => 'scheduler'
]
]
];
Currently I have this:
$groups = [];
$modules = array();
I am iterating over the array $sortMod and group it by group_id where multiple module_id appears i.e group_id 2 and 3 has multiple modules in them. So the result will look what is stated above. Although I know I can have a flag variable $groupExist set to false by default and when the group is pushed into the $groups array, the value is set to false. Then have an if statement check if the value is true, then push just the module values :
foreach($sortMod as $val) {
if(!array_key_exists($val['group_id'],$groups)){
$groups[$val['group_id']] = [];
}
$groups[$val['group_id']][] = $val;
}
echo '<pre>';
print_r($groups);
echo '<pre>';
You can use array_reduce to group the array. If you don't want to make a multidimensional array if the group has only one element, you can use array_map
$sortMod = .. //Your array here.
$grouped = array_reduce($sortMod, function($c, $v){
$c[ $v['group_id'] ][] = $v;
return $c;
}, array());
$result = array_map(function ($n) {
if ( count($n) === 1 ) return $n[0]; //Since the group has one element. Return the element 0.
$newN = array(); //Contruct the new format for 2 or more elements.
$newN['group_id'] = $n[0]['group_id']; //Add the group_id
foreach($n as $value) //Loop thru the array, remove the group_id and push.
{
unset($value['group_id']);
$newN[] = $value;
}
return $newN;
}, $grouped );
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[1] => Array
(
[group_id] => 1
[group_name] => Home
[module_id] => 1
[mod_name] => Home
[mod_link] => /home
[var_name] => home
)
[2] => Array
(
[group_id] => 2
[0] => Array
(
[module_id] => 2
[mod_name] => Numbers
[mod_link] => /number_mapping
[var_name] => numbermap
)
[1] => Array
(
[module_id] => 70
[mod_name] => DR Plan
[mod_link] => /dr_plan
[var_name] => dr_plan
)
)
[3] => Array
(
[group_id] => 3
[0] => Array
(
[module_id] => 8
[mod_name] => Reporting
[mod_link] => /reporting
[var_name] => reporting
)
[1] => Array
(
[module_id] => 80
[mod_name] => Scheduler
[mod_link] => /scheduler
[var_name] => scheduler
)
)
)
Adding some little modifications to your code would make a something like that
$group = [];
foreach ($sortMod as $val){
$current_id = $val['group_id'];
unset($val['group_id']);
if (!array_key_exists($current_id ,$group)){
$group[$current_id] = array();
}
$group[$current_id][] = $val;
}
echo '<pre>';
print_r($groups);
echo '<pre>';
You could add your $val into the group using the group_id. If you find this key, you can create the group_id key. If you find it again, and it's an array, append to it.
$groups = [];
foreach($sortMod as $val)
{
$group_id = $val['group_id'];
if (!isset($groups[$group_id])) { // First case
$groups[$group_id] = $val ;
continue;
}
// regroup if 'group_id' is not an array
if (!is_array($groups[$group_id]['group_id']))
{
unset($groups[$group_id]['group_id']);
$groups[$group_id] = ['group_id' => $group_id, $groups[$group_id]] ;
}
// append the new group
unset($val['group_id']);
$groups[$group_id][] = $val ;
}
// optionnal (to remove group_id keys)
$groups = array_values($groups);
print_r($groups);
Outputs:
Array
(
[0] => Array
(
[group_id] => 1
[group_name] => Home
[module_id] => 1
[mod_name] => Home
[mod_link] => /home
[var_name] => home
)
[1] => Array
(
[group_id] => 2
[0] => Array
(
[module_id] => 2
[mod_name] => Numbers
[mod_link] => /number_mapping
[var_name] => numbermap
)
[1] => Array
(
[module_id] => 70
[mod_name] => DR Plan
[mod_link] => /dr_plan
[var_name] => dr_plan
)
)
[2] => Array
(
[group_id] => 3
[0] => Array
(
[module_id] => 8
[mod_name] => Reporting
[mod_link] => /reporting
[var_name] => reporting
)
[1] => Array
(
[module_id] => 80
[mod_name] => Scheduler
[mod_link] => /scheduler
[var_name] => scheduler
)
)
)
You could use a generic custom function like so:
function array_group_by($a, $i, $rem = true){
foreach($a as $v){
$k = $v[$i];
if($rem){
unset($v[$i]);
}
$t[$k][] = $v;
}
return $t;
}
echo '<pre>';
print_r(array_group_by($sortMod, 'group_id'));
echo '<pre>';
And here is the output.
A group id is supposed to be unique anyways, while this output is not what you specifically wanted it makes a more usable array to loop over.
The first key is the group_id. The following arrays that are in the group array contains are the "modules".
Optionally, you can use array_group_by($sortMod, 'group_id', false); to keep the group_id within that array.
Now when looping over it:
foreach(array_group_by($sortMod, 'group_id') as $groupid => $modules){
echo "$groupid is the group_id and contains " . count($modules) . " modules";
foreach($modules as $module){
echo "Hi from " . $module['module_id'];
}
}
In my opinion, short and reusable code is the way to go.
I am new to php and i want to remove element from array Here is my array:
Array
(
[Total] => 21600000
[Items] => Array
(
[2-13] => Array
(
[Item] => 2
[PID] => 13
[UPrice] => 11000000
[Qty] => 1
[Total] => 11000000
)
[58-167] => Array
(
[Item] => 58
[PID] => 167
[UPrice] => 5300000
[Qty] => 1
[Total] => 5300000
)
)
)
And i want to remove array element by PID.
I have try this but no luck:-
$ShoppingBag =$_SESSION['ssss'];
if ($ShoppingBag !== null && $ShoppingBag['Total'] > 0) {
foreach ($ShoppingBag['Items'] as $IOrder) {
if($IOrder["PID"]==13)
{
unset($ShoppingBag[$IOrder]);
}else
{
}
}
}
Please help. Thanks
You can try with one simple array map :)
$arr = [
'Total' => 21600000,
'Items' => [
'2-13' => [
'Item' => 2,
'PID' => 13,
'UPrice' => 11000000,
'Qty' => 1,
'Total' => 11000000
],
'58-167'=> [
'Item' => 58,
'PID' => 167,
'UPrice' => 5300000,
'Qty' => 1,
'Total' => 5300000
]
]
];
$test = array_map(function($ar) {
foreach($ar as $k=>$i) {
if( isset($i['PID']) && $i['PID'] == '13')
unset($ar[$k]);
}
return $ar; } , $arr);
var_dump($test);
You need 2 loop to do the action you want.
foreach($my_array as $key=>$value)
{
if(is_array($value))
{
foreach($value as $k=>$v)
{
if($k == 'PID')
{
unset($value[$k]);
}
}
}
}
with this you can remove only element with key PID.
Hi youre unsetting the $IOrder instead of the Item that you want to delete:
This code is a solution an i tested it :
$ShoppingBag = Array
(
"Total" => 21600000,
"Items" => Array
(
"2-13" => Array
(
"Item" => 2,
"PID" => 13,
"UPrice" => 11000000,
"Qty" => 1,
"Total" => 11000000,
),
"58-167" => Array
(
"Item" => 58,
"PID" => 167,
"UPrice" => 5300000,
"Qty" => 1,
"Total" => 5300000,
),
),
);
foreach($ShoppingBag["Items"] as $key => $value){
if($value["PID"]==13){
unset($ShoppingBag["Items"][$key]);
}
}
You should know that always when you're using foreach loop the foreach( $a as $b ) when you do something to $b , $a remains the same because tey are different variables :)
Hope it will help you .
Regards.
$arr = [
'Total' => 21600000,
'Items' => [
'2-13' => [
'Item' => 2,
'PID' => 13,
'UPrice' => 11000000,
'Qty' => 1,
'Total' => 11000000
],
'58-167'=> [
'Item' => 58,
'PID' => 167,
'UPrice' => 5300000,
'Qty' => 1,
'Total' => 5300000
]
]
];
$pid_to_remove = 13;
$new_ar = array_filter(
$arr,
function ($v) using ($pid_to_remove) {
return (!isset($v['PID'])) || ($v['PID'] != $pid_to_remove);
}
);
I'm having a problem lately that's driving me crazy. I have a multi-dimensional array like this:
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
)
'2' => array(
'id' => '3',
'name' => 'test',
'cat' => array(
'a' => '50',
'b' => '40',
'c' => '90'
),
'canvas' => '1'
)
)
);
And i want to search on it using a function like this: search('canvas = 1');
That would return all the arrays, child of db, that have a key canvas with the value of 1. Or, for example:
search('a = 15');
Would return all arrays that have a key, child of cat, named a and with a value of 15.
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
)
);
//checks if array $array contains element with $searchKey key, and $searchVal value
function arrayContains($array, $searchVal, $searchKey) {
if (!is_array($array))
return false;
foreach ($array as $key => $value) {
if ($key === $searchKey && $searchVal === $value)
return true;
if (is_array($value) && arrayContains($value, $searchVal, $searchKey))
return true;
}
return false;
}
function search($a, $search) {
list($searchKey, $searchVal) = explode('=', $search);
$result = array();
foreach($a as $val) {
if (arrayContains($val, $searchVal, $searchKey))
$result[] = $val;
}
return $result;
}
print_r(search($a['db'], "a=15"));
print_r(search($a['db'], "canvas=1"));
Which produces this output(outputs sub-arrays of $a['db'] which contain searched key=>value pair):
Array
(
[0] => Array
(
[id] => 1
[name] => test
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
[1] => Array
(
[id] => 2
[name] => test2
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
)
Array
(
[0] => Array
(
[id] => 3
[name] => test
[cat] => Array
(
[a] => 50
[b] => 40
[c] => 90
)
[canvas] => 1
)
)
Just check the below link if this can help you -
http://php.net/manual/en/function.array-search.php
It contains detailed documentation of php function array_search() and various user codes for searching in multi-dimensional array along with user reviews.
function search($array, $canvas)
{
$result = array();
foreach ($array as $k1 => $v1) {
foreach ($v1 as $k2 => $v2) {
if ($v2['canvas'] == $canvas) {
$result[] = $array[$k1][$k2];
}
}
}
return $result;
}
// $a = your array
print_r(search($a, 1));