Recursive multidimensional array search but exclude a certain sub-array? - php

I have the following code. Basically I want to search through the keys of this multidimensional array from top to bottom, but ignore the sub-array with the key specified by $ignoreKey. As you can see by the "array_key_exists" logic, it is currently built for a 1D array.. I tried some examples but having problems (so have left my 1D code as is below).
If all went as planned, I would have "thirtyfromgroup1" echoed.
What would I have to change in the following to achieve this?
$keyCheck = "30";
$ignoreKey = "group2";
if (array_key_exists($keyCheck, $topLevel)) {
echo $topLevel[$keyCheck];
}
$topLevel = array(
"group1" => array
(
"12" => "twelve",
"30" => "thirtyfromgroup1"
),
"group2" => array
(
"14" => "fourteen",
"30" => "thirty"
),
"group3" => array
(
"12" => "twelve",
"26" => "thirty"
),
);

Assuming you just want to ignore keys in the top level of your array, and are just searching the keys in the second level:
$keyCheck = "30";
$ignoreKey = "group2";
$topLevel = array(
"group1" => array(
"12" => "twelve",
"30" => "thirtyfromgroup1"
),
"group2" => array(
"14" => "fourteen",
"30" => "thirty"
),
"group3" => array(
"12" => "twelve",
"26" => "thirty"
),
);
foreach($topLevel as $topKey => $topValue)
{
if ($topKey == $ignoreKey)
continue;
foreach($topValue as $subKey => $subValue)
{
if ($subKey == $keyCheck)
echo $subValue;
}
/* Alternatively:
if (isset($topValue[$keyCheck]))
echo $topValue[$keyCheck];
*/
}

Related

Refactor foreach with multilevel array

I'm currently returning results from a sql statement in an array like so:
$results = [];
foreach($promotionTool as $p){
$results[] = $p;
}
return $results;
Which my console shows in an object with this structure:
(2) [{…}, {…}]
0:
codeID: "41"
code: "123ABC"
rule_type: "Category"
attribute_type: "identifier"
attribute_title: "category number"
attribute_value: "234"
1:
codeID: "41"
code: "123ABC"
rule_type: "Category"
attribute_type: "amount"
attribute_title: "percent"
attribute_value: "25"
This is showing the data I expect but I'm a little bit lost on how to restructure this so that I can group on certain levels and finally return only an array of the attributes like so:
codeID
code
rule_type
array(
0:
attribute_type: "identifier"
attribute_title: "category number"
attribute_value: "234"
1:
attribute_type: "amount"
attribute_title: "percent"
attribute_value: "25"
)
How would I refactor my foreach to group at multiple levels in that way?
I guess this is what you are looking for:
<?php
$input = [
[
'codeID' => "41",
'code' => "123ABC",
'rule_type' => "Category",
'attribute_type' => "identifier",
'attribute_title' => "category number",
'attribute_value' => "234"
],
[
'codeID' => "41",
'code' => "123ABC",
'rule_type' => "Category",
'attribute_type' => "amount",
'attribute_title' => "percent",
'attribute_value' => "25"
]
];
$output = [];
array_walk($input, function ($e) use (&$output) {
$output[$e['codeID']][$e['code']][$e['rule_type']][] = [
'attribute_type' => $e['attribute_type'],
'attribute_title' => $e['attribute_title'],
'attribute_value' => $e['attribute_value']
];
});
print_r($output);
This could be a variant easier to read:
array_walk($input, function ($e) use (&$output) {
$codeID = &$e['codeID'];
$code = &$e['code'];
$rule_type = &$e['rule_type'];
$output[$codeID][$code][$rule_type][] = [
'attribute_type' => $e['attribute_type'],
'attribute_title' => $e['attribute_title'],
'attribute_value' => $e['attribute_value']
];
});
The output obviously is:
Array
(
[41] => Array
(
[123ABC] => Array
(
[Category] => Array
(
[0] => Array
(
[attribute_type] => identifier
[attribute_title] => category number
[attribute_value] => 234
)
[1] => Array
(
[attribute_type] => amount
[attribute_title] => percent
[attribute_value] => 25
)
)
)
)
)

Php find key for min value in 2D array

I have the following 2D array and I would like to get the key of the smalest value in the [0] column if done is equal to no
$graph= array(
"CityA" => array(
"0" => "1",
"1" => "CityC",
"done" => "no",
),
"CityB" => array(
"0" => "4",
"1" => "CityA",
"done" => "no",
),
"CityC" => array(
"0" => "5",
"1" => "CityA",
"done" => "no",
),
);
Try this,
$arr = array_map(function($v){return $v[0];}, $graph);
$key = array_keys($arr, min($arr));
Here you go.
$tes = min( array_column( $graph, 0 ) );
$key = array_search( $tes, array_column( $graph, 0 ) );
$array_keys = array_keys($graph);
echo $array_keys[$key];
You should perform all of your checks in a single pass through your array.
My snippet will provide the first qualifying (contains the lowest [0] value AND has a done value of no) row's key.
Code: (Demo)
$graph = [
"CityB" => ["0" => "1", "1" => "CityA", "done" => "no"],
"CityA" => ["0" => "1", "1" => "CityC", "done" => "no"],
"CityD" => ["0" => "1", "1" => "CityD", "done" => "yes"],
"CityC" => ["0" => "5", "1" => "CityA", "done" => "no"]
];
$result = [];
foreach ($graph as $key => $row) {
if ($row['done'] === 'no' && (!isset($result[$key]) || $row[0] < $result[$key])) {
$result[$key] = $row[0];
}
}
echo key($result) ?? 'No "done => no" rows';
Output:
CityB

Compare multidimensional array with each other and some array field with external variable

I have an array like below. I need to compare with each other and return the matching array on the first index and followed by other.
How can we compare whole array each other based on id and scid with $scid?
$scid = 307;
$array = array(
0 =>
array(
'id' => '485',
'scid' => 306
),
1 =>
array(
'id' => '484',
'scid' => null
),
2 =>
array(
'id' => '486',
'scid' => 305
),
3 =>
array(
'id' => '485',
'scid' => 307
),
4 =>
array(
'id' => '485',
'scid' => 309
),
5 =>
array(
'id' => '485',
'scid' => 329
),
);
The result array should be like
array(3) {
[485]=> array(2) { ["id"]=> string(3) "485" ["scid"]=> int(307) }
[484]=> array(2) { ["id"]=> string(3) "484" ["scid"]=> NULL }
[486]=> array(2) { ["id"]=> string(3) "486" ["scid"]=> int(305) }
}
If array has duplicate id on which scid is not matching then we can pick any id value.
Note :The matching sub array should always be the first index of resulting array.An amount will always be unique and might contain null as well in array.
You want something like this?
$result = [];
foreach ($array as $item) {
$result[$item['id']] = ['id' => $item['id'], 'scid' => $item['scid']];
}
var_dump($result);
Try this,
$temp = [];
foreach($array as $k => $v){
$temp[$v['id']][] = $v;
}
Give it a try, this will work.

How do you remove some array from foreach

i'm trying to remove some array from foreach
example for "result" array :
$result= array (
"1" => array(
"nickname" => "Jow",
"Age"=> "19"
),
"2" => array(
"nickname" => "Rayan",
"Age"=> "25"
),
"3" => array(
"nickname" => "Jinx",
"Age"=> "21"
),
);
i want remove array 1 by nickname
mycode :
foreach ($result as $client => $value){
if ( $value["nickname"] == "Jow"){
unset($result[$client]);
}
echo $value["nickname"].'<p>';
}
Eventually i want The remaining names like Rayan and Jinx
use array_filter ?
$result= array (
"1" => array(
"nickname" => "Jow",
"Age"=> "19"
),
"2" => array(
"nickname" => "Rayan",
"Age"=> "25"
),
"3" => array(
"nickname" => "Jinx",
"Age"=> "21"
),
);
$arr = array_filter($result, 'filter_by_name');
var_dump($arr);exit;
function filter_by_name($value){
if ($value['nickname']=='Jow') {
return false;
} else {
return true;
}
}
Are you looking for something like this?
function removeByNickName($nickName, $array)
{
$temp = array();
foreach($array as $index => $ar)
{
if($array['nickname'] != $nickName) array_push($temp, $ar);
}
return $temp;
}

Sorting array by value

I have this array:
array(
"tour_0" => 1446,
"tour_1" => 1471,
"date-from-1471" => "2014-08-07",
"date-to-1471" => "2014-08-15",
"tour_2" => 30,
"date-from-30" => 2014-08-01,
"date-to-30" => 2014-08-05,
"tour_3" => 10
)
Now, i need it to be sorted to this:
array(
"0" => array("ID" => 1446),
"1" => array("ID" => 1471, "from" => "2014-08-07", "to" => "2014-08-15"),
"2" => array("ID" => 30, "from" => "2014-08-07", "to" => "2014-08-15"),
"3" => array("ID" => 10),
)
How can i accomplish this thing?
I've tried all sorts of things but i can't seem to figure this one out...
Thank's and sorry about the title but i just don't know how to describe it.
How about this?
$ret = [];
foreach($inputArray as $key => $value) {
if (preg_match('/^tour_([0-9]+)/', $key)) {
$ret[$value] = ["ID" => $value];
}
if (preg_match('/date-from-([0-9]+)/', $key, $matches)) {
$ret[$matches[1]]["from"] = $value;
}
if (preg_match('/date-to-([0-9]+)/', $key, $matches)) {
$ret[$matches[1]]["to"] = $value;
}
}
print_r($ret);
/*
Array
(
"1446" => Array ("ID" => 1446),
"1471" => Array ("ID" => 1471, "from" => "2014-08-07", "to" => "2014-08-15"),
"30" => Array ("ID" => 30, "from" => "2014-08-01", "to" => "2014-08-05"),
"10" => Array ("ID" => 10)
)*/
Close enough? (it is quite trival change the keys of the array, considering they are in order (0, 1, 2, 3, ...), if they are not, maybe you can save the order also (in another item of the subarray) and recompose again once this array is formed)

Categories