Foreach Array error (PHP) - php

I want to create dynamic menu with looping an array be 1 object menu. But error occured.
Our code is below it:
$menus = [{"id" => 1, "label" => "content", "parent_id" => 0},{"id" => 2, "label" => "inbox", "id" => 3, "parent_id" => 0}, {"id" => 4, "label" => "item", "parent_id" => 0}];
$sub_menus = [{"id" => 5, "label" => "banner", "parent_id" => 1},{"id" => 6, "label" => "ads", "parent_id" => 1}];
foreach($menus as $row => $value){
$nav[$row] = $value;
foreach($sub_menus as $r => $v) {
if($v['parent_id'] == $value['id']){
$nav[$row]['sub_menu'][$r] = $v;
}
}
}
I get error notif, "Indirect modification of overloaded element of App\Menu has no effect"
Please Help me :)

The code is working. You have a lot of bugs in your arrays.
Fixed:
$menus = [
[
"id" => 1,
"label" => "content",
"parent_id" => 0
],
[
"id" => 2,
"label" => "inbox",
"parent_id" => 0
],
[
"id" => 4,
"label" => "item",
"parent_id" => 0
]
];
$sub_menus = [
[
"id" => 5,
"label" => "banner",
"parent_id" => 1
],
[
"id" => 6,
"label" => "ads",
"parent_id" => 1
]
];
foreach($menus as $row => $value){
$nav[$row] = $value;
foreach($sub_menus as $r => $v) {
if($v['parent_id'] == $value['id']){
$nav[$row]['sub_menu'][$r] = $v;
}
}
}

You have a broken array, something like an incorrect conversion of json to an array;
You can test(execute) it here (working example)

Related

Php Recursivity: Convert a multidimensional associative array into an array that contains each level of data

I am looking for the best way to convert a multidimensional associative array into a new array, where each row is the concatenation of each column ex :
$datas[] = [
"id" => "1000",
"parent" => "0",
"level" => "1",
"children" => [
[
"id" => "1001",
"parent" => "1000",
"level" => "2",
"children" => [
[
"id" => "1002",
"parent" => "1001",
"level" => "3",
"children" => [
[
"id" => "1003",
"parent" => "1002",
"niveau" => "4",
],
[
"id" => "1004",
"parent" => "1002",
"niveau" => "4",
],
[
"id" => "1005",
"parent" => "1002",
"niveau" => "4",
]
]
],
[
]
]
],
[
"id" => "1006",
"parent" => "1000",
"level" => "2"
]
],
[
"id" => "1007",
"parent" => "0",
"level" => "1"
]
];
Here's my method :
public function recursData(array $datas, &$str ="", &$row =[], int $level = 0)
{
$level++;
foreach ($datas as $data) {
foreach($data as $key => $d) {
if (is_array($d)) {
$this->recursData($d, $str, $row,$level);
} else {
$str.= "{$level}_{$key}_{$d}|";
if ($key == "parent") {
$row[] = $str;
}
}
}
}
return $row;
}
Output (not what i'm looking for) :
array:8 [
0 => "1_id_1000|1_parent_0|"
1 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|"
2 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|"
3 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|"
4 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|"
5 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|4_id_1005|4_parent_1002|"
6 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|4_id_1005|4_parent_1002|2_id_1006|2_parent_1000|"
7 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|4_id_1005|4_parent_1002|2_id_1006|2_parent_1000|1_id_1007|1_parent_0|"
]
The output i'm looking for:
array:8 [
0 => "1_id_1000|1_parent_0"
1 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000"
2 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001"
3 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|3_parent_1002"
4 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1004|3_parent_1002"
5 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1005|3_parent_1002"
6 => "1_id_1000|1_parent_0|2_id_1006|2_parent_1000"
7 => "1_id_1007|1_parent_0"
]
I'm stuck to finish this properly, I tried lot of things, but can't understand what to do obtain what I want to resolve this. Hope someone could help :)

Merging the two array of arrays based on a field value

There are two arrays of arrays. $user and $experience are two arrays and i want to achieve $final as my expected output.
I have two arrays:
$user = [
[
"country" => "aus",
"new_experiences" => 0,
"new_users" => 6
],
[
"country" => "jpn",
"new_experiences" => 0,
"new_users" => 5
]
];
$experience = [
[
"country" => "jpn",
"new_experiences" => 12,
"new_users" => 0
],
[
"country" => "usa",
"new_experiences" => 10,
"new_users" => 0
]
];
After merging these two arrays based on country, how can i get:
$final = [
[
"country" => "aus",
"new_experiences" => 0,
"new_users" => 6
],
[
"country" => "jpn",
"new_experiences" => 12,
"new_users" => 5
],
[
"country" => "usa",
"new_experiences" => 10,
"new_users" => 0
]
];
Try this
array_unique(array_merge($array1,$array2), SORT_REGULAR);
http://se2.php.net/manual/en/function.array-unique.php
You can achieve your GOal using this simple steps:
Iterate and arrange your array into a single array using foreach
Create a key-value array, just like I have created $issetArray
Push all the value in a $final array, you will get the desired output
I have created a simple logic using foreach loop, isset() and array_push()
$user = array(
array(
"country" => "aus",
"new_experiences" => 0,
"new_users" => 6
),
array(
"country" => "jpn",
"new_experiences" => 0,
"new_users" => 5
)
);
$experience = array(
array(
"country" => "jpn",
"new_experiences" => 12,
"new_users" => 0
),
array(
"country" => "usa",
"new_experiences" => 10,
"new_users" => 0
)
);
$final = array();
$issetArray = array();
foreach($user as $key => $value)
{
if(isset($issetArray[$value['country']]))
{
$issetArray[$value['country']]['new_experiences'] = $value;
$issetArray[$value['country']]['new_users'] = $value;
}
else
{
$issetArray[$value['country']] = $value;
}
}
foreach($experience as $key => $value)
{
if(isset($issetArray[$value['country']]))
{
$issetArray[$value['country']]['new_experiences'] = $value['new_experiences'];
$issetArray[$value['country']]['new_users'] = $value['new_users'];
}
else
{
$issetArray[$value['country']] = $value;
}
}
foreach($issetArray as $value)
{
array_push($final, $value);
}
echo "<pre>";
print_r($final);
Click on the link to know more about isset() and array_push()

Convert PHP Array from One to Multi-dimensional Based on Parent ID Values

I've got a one-dimensional array of objects that represent multi-dimensional data:
array(
array(
"id" => 1,
"parent_id" => 0,
"content" => 'des'
),
array(
"id" => 2,
"parent_id" => 3,
"content" => 'abc'
),
array(
"id" => 3,
"parent_id" => 1,
"content" => 'jjjj'
),
array(
"id" => 4,
"parent_id" => 5,
"content" => 'dsfsd'
),
array(
"id" => 5,
"parent_id" => 0,
"content" => 'dsfsd'
)
);
How should I convert it into a multi-dimensional array?
array(
array(
"id" => 1,
"parent_id" => 0,
"content" => 'des'
),
array(
"id" => 3,
"parent_id" => 1,
"content" => 'jjjj'
),
array(
"id" => 2,
"parent_id" => 3,
"content" => 'abc'
),
array(
"id" => 5,
"parent_id" => 0,
"content" => 'dsfsd'
),
array(
"id" => 4,
"parent_id" => 5,
"content" => 'dsfsd'
)
);
I'd like to sort by id and children after the parent, if parent_id = 0 it is the root element. Thanks everybody very much!
I think you need to sort the array by parent_id.
array_sort() a laravel helper function : https://laravel.com/docs/5.7/helpers#method-array-sort
$sorted = array_sort($array, 'parent_id');
output
array:5 [▼
0 => array:3 [▼
"id" => 1
"parent_id" => 0
"content" => "des"
]
4 => array:3 [▼
"id" => 5
"parent_id" => 0
"content" => "dsfsd"
]
2 => array:3 [▼
"id" => 3
"parent_id" => 1
"content" => "jjjj"
]
1 => array:3 [▼
"id" => 2
"parent_id" => 3
"content" => "abc"
]
3 => array:3 [▼
"id" => 4
"parent_id" => 5
"content" => "dsfsd"
]
]
this is my code (done)
function sort($array){
$newArray = [];
sortLoop($array, $newArray);
return $newArray;
}
function sortLoop($array, &$newArray, $parent_id = 0){
foreach ($array as $key => $item) {
if ($item['parent_id'] == $parent_id) {
$newArray[] = $item;
unset($array[$key]);
sortLoop($array,$newArray, $item['id']);
}
}
}
Wish this useful for someone.

Merge two pairs in the same array if the pairs have the same value

I have the following pairs and they are in the same array:
[
["ID" => 0, "User" => "Test" , "Type" => 3, "Target" => "Caris"],
["ID" => 1, "User" => "Test1", "Type" => 3, "Target" => "Caris"],
["ID" => 2, "User" => "Test2", "Type" => 4, "Target" => "Shirone"],
["ID" => 3, "User" => "Test3", "Type" => 3, "Target" => "Caris"]
]
I want to get the kinds of them, so I using the following code:
$SortList = [];
foreach($Notif as $Key => $Value)
array_push($SortList, ['Type' => $Value['Type'],
'Target' => $Value['Target']]);
and get this:
[
["Type" => 3, "Target" => "Caris"],
["Type" => 3, "Target" => "Caris"],
["Type" => 4, "Target" => "Shirone"],
["Type" => 3, "Target" => "Caris"]
]
But what I really want is something like this:
[
["Type" => 3, "Target" => "Caris"],
["Type" => 4, "Target" => "Shirone"]
]
I want to merge the pairs if they were same value,
(array_merge() seems can only used for non-pair)
How can I merge them like something above?
$SortList = [];
foreach($Notif as $Key => $Value) {
// Just save only value for the same pair, use them concatenated as the key
$SortList[$Value['Type']."_".$Value['Target']] =
array('Type' => $Value['Type'], 'Target' => $Value['Target']);
}
// remove extra stuff (the keys) that was added to prevent duplicates
$SortList = array_values($SortList);

Populate multidimensional array's rank column with dense rank number

My array structure is as follows -
[
[
"points" => 10,
"details" => ["name" => "Team A", "rank" => ""]
],
[
"points" => 10,
"details" => ["name" => "Team B", "rank" => ""]
],
[
"points" => 8,
"details" => ["name" => "Team C", "rank" => ""]
],
[
"points" => 6,
"details" => ["name" => "Team D", "rank" => ""]
],
]
Now I want populate the array's "rank" value with the appropriate dense rank. Expected result:
[
[
"points" => 10,
"details" => ["name" => "Team A", "rank" => 1]
],
[
"points" => 10,
"details" => ["name" => "Team B", "rank" => 1]
],
[
"points" => 8,
"details" => ["name" => "Team C", "rank" => 2]
],
[
"points" => 6,
"details" => ["name" => "Team D", "rank" => 3]
],
]
How can I achieve this output? I tried looping through each element in the array and comparing points, but I didn't find that to be really efficient.
How about to create another array and store desired result there
$array = array(
array(
"points" => 10,
"details" => array(
"name" => "Team A",
"rank" => ""
)
),
array(
"points" => 11,
"details" => array(
"name" => "Team B",
"rank" => ""
)
)
);
$c = 0; // count identifier
$n = array(); // create new array
for ($i=0;$i<count($array);$i++){ // loop through each array
foreach ($array[$i] as $value){ // loop through into sub arrays
if (is_array($value)){
$n[$i]['details'] = array(
"name" => $value['name'],
"rank" => $c
);
$c++;
} else {
$n[$i]['points'] = $value;
}
}
}
print_r($n);
Output will be:
Array ( [0] => Array ( [points] => 10 [details] => Array ( [name] => Team A [rank] => 0 ) ) [1] => Array ( [points] => 11 [details] => Array ( [name] => Team B [rank] => 1 ) ) )
A bit bruteforce but it should work.
$array = array(
array(
"points" => 10,
"details" => array(
"name" => "Team A",
"rank" => ""
)
),
array(
"points" => 11,
"details" => array(
"name" => "Team B",
"rank" => ""
)
),
array(
"points" => 10,
"details" => array(
"name" => "Team A",
"rank" => ""
)
),
array(
"points" => 11,
"details" => array(
"name" => "Team B",
"rank" => ""
)
)
);
$points = array();
foreach($array as $key => $arr){
$points[] = $arr['points'];
}
asort($points);
foreach($points as $pkey => $point){
foreach($array as $akey => $arr){
if($point == $arr['points']){
$array[$akey]['details']['rank'] = $pkey+1;
}
}
}
var_dump($array);
Since your multidimensional input array is already sorted descending by the points column, you can loop through the array and modify its rank data by reference while conditionally incrementing the rank variable.
Code: (Demo)
$denseRank = 0;
foreach ($array as ['points'=> $points, 'details' => ['rank' => &$rank]]) {
$denseRanks[$points] ??= ++$denseRank;
$rank = $denseRanks[$points];
}
var_export($array);
The above snippet uses "array destructuring" in the foreach() to declare only used variables; it is just as viable to declare &$row and then access its elements in the loop's body.

Categories