I am having three arrays
topicsSelected
relavantGroups
topicAssingned
$topicsSelected = [ "T-100","T-600"];
$relavantGroups = [
[ "id" => "G-001","name" => "3 A","active" => false ],
["id" => "G-002","name" => "3 B","active" => false]
];
$topicAssingned = [
"G-001" => [
"groupID" => "G-001",
"groupName" => "3 A",
"topics" => [
"T-100" => [
"topicID" => "T-100"
],
"T-200" => [
"topicID" => "T-200"
]
]
],
"G-002" => [
"groupID" => "G-002",
"groupName" => "3 B",
"topics" => [
"T-400" => [
"topicID" => "T-400"
],
"T-500" => [
"topicID" => "T-500"
]
]
],
];
$topicsSelected array values at least one value should present $topicAssingned means based on groupID, i have to push one value to $relavantGroups like disable : D suppose value not present means disable : A
Expected output:
[
"id" => "G-001",
"name" => "3 A",
"active" => false,
"disable" => "D"
],
[
"id" => "G-002",
"name" => "3 B",
"active" => false,
"disable" => "A"
]
<?php
$topicsSelected = [ "T-100","T-600"];
$relavantGroups = [
[ "id" => "G-001","name" => "3 A","active" => false ],
["id" => "G-002","name" => "3 B","active" => false]
];
$topicAssigned = [
"G-001" => [
"groupID" => "G-001",
"groupName" => "3 A",
"topics" => [
"T-100" => [
"topicID" => "T-100"
],
"T-200" => [
"topicID" => "T-200"
]
]
],
"G-002" => [
"groupID" => "G-002",
"groupName" => "3 B",
"topics" => [
"T-400" => [
"topicID" => "T-400"
],
"T-500" => [
"topicID" => "T-500"
]
]
],
];
$topic_selected_map = [];
foreach($topicsSelected as $each_topic){
$topic_selected_map[$each_topic] = true;
}
$relevant_group_map = [];
foreach($relavantGroups as $each_group){
$relevant_group_map[$each_group['id']] = $each_group;
}
$result = [];
foreach($topicAssigned as $each_assigned_topic){
if(!isset($relevant_group_map[$each_assigned_topic['groupID']])) continue;
$topics_not_found = true;
foreach($each_assigned_topic['topics'] as $each_topic => $topic_details){
if(isset($topic_selected_map[$each_topic])){
$topics_not_found = false;
break;
}
}
$result[] = [
'id' => $each_assigned_topic['groupID'],
'name' => $each_assigned_topic['groupName'],
'active' => $relevant_group_map[$each_assigned_topic['groupID']]['active'],
'disable' => ($topics_not_found === true ? 'A' : 'D')
];
}
print_r($result);
Output:
Array
(
[0] => Array
(
[id] => G-001
[name] => 3 A
[active] => false
[disable] => D
)
[1] => Array
(
[id] => G-002
[name] => 3 B
[active] => false
[disable] => A
)
)
First, make a map(associative array) of values of $topicsSelected. Same goes for $relavantGroups. This is to make the check more efficient. See more on Hash Table.
Now, iterate over $topicAssigned and then iterate over each group's topics inside it. Now, check if a topic exists inside $topicsSelected using a simple isset function. If yes, we disable them, else we don't.
It's not very clear what you are asking and the code is a bit weird but I'll give it a try.
First fix your array declaration - you should use => and not :;
You have to Iterate over the $relavantGroups and for each element iterate the $topicAssingned array. Then perform a simple comparison to see if the group Id is present and you are done!
Here is my solution (quick and dirty): You can see it here
foreach ($relavantGroups as &$g) {
$found = false;
foreach ($topicAssingned as $key => $assigned) {
if ($key === $g["id"] && is_array($assigned["topics"])) {
foreach ($assigned["topics"] as $topic) {
if (in_array($topic["topicID"], $topicsSelected)) {
$found = true;
break;
}
}
}
}
$g["disable"] = $found ? "D" : "A";
}
var_dump($relavantGroups);
Updated the solution - note that I'm using in_array() to determine if the topicID is present. That mean that any value that is in the $topicsSelected array will affect the result.
Hope I helped.
This will output (based one your example):
array(2) {
[0]=> array(4) {
["id"]=> string(5) "G-001"
["name"]=> string(3) "3 A"
["active"]=> bool(false)
["disable"]=> string(1) "D"
}
[1]=> array(4) {
["id"]=> string(5) "G-002"
["name"]=> string(3) "3 B"
["active"]=> bool(false)
["disable"]=> string(1) "A"
}
}
Related
I have nth level of nested array with string naming key , I want to convert that in indexing key only for array of item key.
i tried it to convert but that conversation only possible for limited level of nested array rather than nth level .
Input array:
$input_array= [
"NOCPL-All -working" => [
"name" => "NOCPL-All -working",
"item" => [
"apis for web" => [
"name" => "apis for web",
"item" => [
"0" => [
"name" => "update user branch maps"
]
]
],
"update user web" => [
"name" => "update user web",
"item" => [
"0" => [
"name" => "update user"
],
"1" => [
"name" => "add user"
]
]
]
]
]
];
I tried below code to convert indexing of 'item' nested array for limited level
function cleanArrayKeys($arr) {
foreach($arr as $k=>$arr1) {
if(isset($arr[$k]['item'])) {
$arr[$k]['item'] = array_values($arr[$k]['item']);
foreach($arr[$k]['item'] as $k1=>$arr2) {
if(isset($arr[$k]['item'][$k1]['item'])) {
$arr[$k]['item'][$k1]['item'] = array_values($arr[$k]['item'][$k1]['item']);
foreach($arr[$k]['item'][$k1]['item'] as $k3=>$arr3) {
if(isset($arr[$k]['item'][$k1]['item'][$k3]['item'])) {
$arr[$k]['item'][$k1]['item'][$k3]['item'] = array_values($arr[$k]['item'][$k1]['item'][$k3]['item']);
foreach($arr[$k]['item'][$k1]['item'][$k3]['item'] as $k4=>$arr4) {
if(isset($arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item'])) {
$arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item'] = array_values($arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item']);
foreach($arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item'] as $k5=>$arr5) {
if(isset($arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item'][$k5]['item'])) {
$arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item'][$k5]['item'] = array_values($arr[$k]['item'][$k1]['item'][$k3]['item'][$k4]['item'][$k5]['item']);
}
}
}
}
}
}
}
}
}
}
return $arr;
}
print_r(cleanArrayKeys($input_array));
?>
Expected Output :
[
"NOCPL-All -working" => [
"name" => "NOCPL-All -working",
"item" => [
"0" => [
"name" => "apis for web",
"item" => [
"0" => [
"name" => "update user branch maps"
],
"1" => [
"name" => "add user branch maps"
]
]
],
"1" => [
"name" => "update user web",
"item" => [
"0" => [
"name" => "update user"
]
]
]
]
]
];
Try using a recursion:
function aValues(&$arr) {
if (array_key_exists('item', $arr)) {
$arr['item'] = array_values($arr['item']);
}
foreach ($arr['item'] as &$el) {
if (array_key_exists('item', $el)) {
aValues($el);
}
}
}
aValues($input_array);
print_r($input_array);
i have 1 array like below :
0 => array:4 [
"id" => "1"
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
]
1 => array:4 [
"id" => "2"
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
]
now what i want to do ?? as you can see the date and from_time and to_time have the same value . i want to merge them to 1 item like below :
0 => array:4[
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
"id" => ["1" , "2"]
].
so i can have the same day ids in 1 index of array and if for example the same date and time got 4 ids i get the id key with 4ids . i used array_merge_recursive but it didnt help me with the same keys of an array
this is how i am building the array :
foreach ($arrays as $key => $array) {
$options[$key]['id'] = last(str_split($array['id']));
$options[$key]['date'] = substr($array['id'],0,-2);
$options[$key]['from_time'] = Carbon::createFromTimestamp($array['pickup']['from'])->format('H');
$options[$key]['to_time'] = Carbon::createFromTimestamp($array['pickup']['to'])->format('H');
}
. thanks in advance for help
<?php
//define items
$items = [
[
"id" => "1",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14",
],[
"id" => "2",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14",
]
];
$options = [];
//loop through the items
foreach ($items as $item) {
//set up the hashing key to use to locate if we hit dup entry
$key = "{$item['date']}-{$item['from_time']}-{$item['to_time']}";
//if indexing key not in options = never looked at it before
if (!array_key_exists($key, $options)) {
//have the key points to the current entry
$options[$key] = $item; //attach the whole item to it
//we want the id to be an array to initialize it to be one
$options[$key]['id'] = [];
}
//gets here then we know options[$key] exists
//if the item id not in the id array of our dict
if (!in_array($item['id'], $options[$key]['id'])) {
//add to it
$options[$key]['id'][] = $item['id'];
}
}
//array_values to get the values and not worry about the keys
print_r(array_values($options));
You can do something like this:
$arr = [
[
"id" => "1",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14"
],
[
"id" => "2",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14"
],
[
"id" => "3",
"date" => "2021-08-03",
"from_time" => "14",
"to_time" => "16"
]
];
$res = array_reduce($arr, function($carry, $entry) use(&$arr) {
$matches = array_filter($arr, function($item) use($entry) {
return $item['from_time'] === $entry['from_time'] && $item['to_time'] && $entry['to_time'];
});
//print_r([ $entry['id'], $matches ]);
foreach($matches as $match) {
unset($arr[array_search($match['id'], array_column($matches, 'id'))]);
}
if (!count($matches)) {
return $carry;
}
$carry[] = [
'id' => array_column($matches, 'id'),
'date' => $entry['date'],
'from_time' => $entry['from_time'],
'to_time' => $entry['to_time'],
];
return $carry;
}, []);
I got a recursive function which currently echo the results. I want this function to return results and loop them with foreach inside markup.
I understand that i should use some kind of iteration for each array to get my desired result but have failed with that. Currently my code look like this(with attempts to iterate):
public static function recursiveChildCategory($categories = array(), $depth = 0, $i = 0) {
$ca = [];
// Loop through categories
foreach($categories as $key => $category){
echo str_repeat(" ", $depth);
echo "<a href='".implode('/', $category['breadcrumb'])."'>{$category['title']}</a>";
echo '<br>';
$ca[$i] = [
'id' => $category['id'],
'title' => $category['title'],
];
if(isset($category['child'])) {
// Loop
self::recursiveChildCategory($category['child'], $depth + 1, $i++);
}
}
return $ca;
}
And incoming array to the function:
Array (
[0] => Array (
[id] => 7
[title] => Deserts
[slug] => deserts
[child] => Array (
[0] => Array (
[id] => 8
[title] => Space
[slug] => space
[child] => Array (
[0] => Array (
[id] =>
[title] =>
[slug] =>
[child] => Array ( )
)
)
)
)
)
)
Currently it just returns first level of child categories "Deserts", but nothing about "Space".
As desired result i want function to return all categories with $depth and infinite path to multiple child categoires (to do the same work as currently echo doing).
Thanks in advice
Try this and tell me if it's what you are looking for :
The array for my test :
$array = [
0 => [
"id" => 7,
"title" => "Deserts",
"slug" => "deserts",
"child" => [
0 => [
"id" => 8,
"title" => "Space",
"slug" => "space",
"child" => [
0 => [
"id" => 9,
"title" => "Test",
"slug" => "test"
]
]
]
]
]
];
The recursive function :
function recursiveChildCategory($categories, $depth = 0, $ca = []) {
// Loop through categories
foreach($categories as $key => $category){
$ca[$depth] = [
'id' => $category['id'],
'title' => $category['title'],
];
if(isset($category['child'])) {
// Loop
$ca = recursiveChildCategory($category['child'], $depth + 1, $ca);
} else {
break;
}
}
return $ca;
}
Now, how to use it :
$test = recursiveChildCategory($array);
var_dump($test);
And this is the output :
array(3) {
[0]=>
array(2) {
["id"]=>
int(7)
["title"]=>
string(7) "Deserts"
}
[1]=>
array(2) {
["id"]=>
int(8)
["title"]=>
string(5) "Space"
}
[2]=>
array(2) {
["id"]=>
int(9)
["title"]=>
string(4) "Test"
}
}
Here is a link to test it : http://sandbox.onlinephpfunctions.com/
EDIT : I made some modification because in OP example array can have multiple result in first "depth", here is the "new" solution :
The array for test :
$array = [
"0" =>
[ "id" => 3, "title" => "Subcat", "slug" => "subcat", "child" =>
[ "0" =>
[ "id" => 5, "title" => "Subsubcat2", "slug" => "subcat2", "child" =>
[ "0" =>
[ "id" => "", "title" => "", "slug" =>"", "breadcrumb" => [ "0" => "homeworld", "1" => "cat", "2" => "subcat", "3" => "subcat2" ], "child" => [ ] ]
]
]
]
],
"1" =>
[ "id" => 4, "title" => "Kalahari", "slug" => "kalahari", "child" =>
[ "0" => [ "id" => 7, "title" => "deserts", "slug" => "deserts", "child" =>
[ "0" =>
[ "id" => 8, "title" => "Ural", "slug" => "ural", "child" =>
[ "0" => [ "id" =>"", "title" =>"", "slug" =>"", "child" => [ ] ] ]
]
]
]
]
]
];
The function : I just add $ca[$depth][] instead of $ca[$depth]
function recursiveChildCategory($categories, $depth = 0, $ca = []) {
// Loop through categories
foreach($categories as $key => $category){
$ca[$depth][] = [
'id' => $category['id'],
'title' => $category['title'],
];
if(isset($category['child'])) {
// Loop
$ca = recursiveChildCategory($category['child'], $depth + 1, $ca);
} else {
break;
}
}
return $ca;
}
And now the result :
$test = recursiveChildCategory($array);
foreach ($test as $depth => $c) {
echo "depth : ".$depth."\n";
foreach ($c as $result) {
echo "Title : ".$result['title']."\n";
}
echo "=============\n";
}
The output is :
depth : 0
Title : Subcat
Title : Kalahari
=============
depth : 1
Title : Subsubcat2
Title : deserts
=============
depth : 2
Title :
Title : Ural
=============
depth : 3
Title :
=============
Test here : link
This question already has answers here:
Merge two 2d arrays by shared column value
(6 answers)
Closed 5 months ago.
i want to join two arrays where 1 key should join them.
array:1 [
0 => array:2 [
"MONAT" => "AUG"
"MAIL_CNT" => "2"
]
1 => array:2 [
"MONAT" => "JUL"
"MAIL_CNT" => "1"
]
]
array:2 [
0 => array:2 [
"MONAT" => "AUG"
"ORDER_CNT" => "18"
]
1 => array:2 [
"MONAT" => "JUL"
"ORDER_CNT" => "1"
]
]
The result should be something like
array:1 [
0 => array:2 [
"MONAT" => "AUG"
"MAIL_CNT" => "2"
"ORDER_CNT" => "18"
]
1 => array:2 [
"MONAT" => "JUL"
"MAIL_CNT" => "1"
"ORDER_CNT" => "1"
]
]
I cant figure out what to do.
Thanks in advance and greetings !
use array_replace_recursive
$array = array_replace_recursive($a1, $a2);
you should use php array_replace_recursive() for this
$arr1=array(
0 =>array(
"MONAT" => "AUG",
"MAIL_CNT" => "2"
),
1 => array(
"MONAT" => "JUL",
"MAIL_CNT" => "1"
)
);
$arr2=array(
0 => array(
"MONAT" => "AUG",
"ORDER_CNT" => "18"
),
1 => array(
"MONAT" => "JUL",
"ORDER_CNT" => "1"
)
);
$array = array_replace_recursive($arr1, $arr2);
echo"<pre>"; print_r($array);
$mergedArray = array();
foreach( $arr1 as $key => $row) {
$mergedArray[$key] = array_merge($arr2[$key], $row)
}
hope this helps
1st : simple use array_merge
2nd : & means it is passed by reference instead of value
foreach( $array1 as $key => &$val) {
$val = array_merge($val,$array2[$key]);
}
print_r($array1);
Note : Above code will work only if both array count is same otherwise it will throw the error .
I have an array that looks like this
"name" => array:3 [
1 => "Hello"
4 => "Test"
21 => "Test2"
]
"runkm" => array:3 [
1 => "100.00"
4 => "1000.00"
21 => "2000.00"
]
"active" => array:3 [
1 => "1"
4 => "0"
21 => "0"
]
Can i somehow combine the matching keys with a PHP function so that the array would look like this instead
1 => array:3 [
name => "Hello"
runkm => "100.00"
active => "1"
]
4 => array:3 [
name => "Test"
runkm => "1000.00"
active => "0"
]
21 => array:3 [
name => "Test2"
runkm => "2000.00"
active => "0"
]
EDIT: Thanks for all the answers guys. What i was really looking for was a PHP built in function for this, which i probably should have been more clear about.
$newArr=array();
foreach($array1 as $key => $value){
$newArr[$key]=>array(
'name' =>$value[$key];
'runkm' =>$array2[$key];
'active'=>$array3[$key];
);
}
this is how you make a new array and then print the $newArr and check you get what you want or not? Good Luck!
<?php
$resultarr = array();
for($i=0;$i<count($sourcearr['name']);$i++) {
$resultarr[] = array('name'=>$sourcearr['name'][$i], 'runkm'=>$sourcearr['runkm'][$i], 'active'=>$sourcearr['active'][$i]);
}
This works well. And also, doesn't use hard coded keys.
<?php
$arr = [
"name" => [
1 => "Hello",
4 => "Test",
21 => "Test2"
],
"runkm" => [
1 => "100.00",
4 => "1000.00",
21 => "2000.00"
],
"active" => [
1 => "1",
4 => "0",
21 => "0"
]
];
// Pass the array to this function
function extractData($arr){
$newarr = array();
foreach ($arr as $key => $value) {
foreach($value as $k => $v) {
if(!isset($newarr[$k]))
$newarr[$k] = array();
$newarr[$k][$key] = $v;
}
}
return $newarr;
}
print_r(extractData($arr));
?>
I'm not sure if there's a function that does that in PHP but maybe you can try this
$arr1 = array(
"name" => array(
1 => "hello",
4 => "test",
21 => "test2",
),
"runKm" => array(
1 => "100",
4 => "200",
21 => "300",
),
"active" => array(
1 => "1",
4 => "0",
21 => "0",
),
);
// declare another that will hold the new structure of the array
$nArr = array();
foreach($arr1 as $key => $val) {
foreach($val as $sub_key => $sub_val) {
$nArr[$sub_key][$key] = $sub_val;
}
}
what this does is simply loop thru each array and its values and assign it to another array which is the $nArr. I hope it helps.