Getting error T_DOUBLE_ARROW for multi dimensional associative array - php

I am testing out a recursive PHP script. But the associative array beginning with "items" key is throwing back the error T_DOUBLE_ARROW. Do I need to use brackets for this portion? The "methods" key is a layer within the "items" keys. Can someone guide me to how I can fix this error? The find_in_arr function works fine when calling name, subject and type keys. But when it gets to items I get the error.
<?php
function find_in_arr($key, $arr)
{
foreach ($arr as $k => $v)
{
if ($k == $key)
{
return $v;
}
if (is_array($v))
{
foreach ($v as $_k => $_v)
{
if ($_k == $key)
{
return $_v;
}
}
}
}
return false;
}
$arr =
array(
"name" => "Php Master",
"subject" => "Php",
"type" => "Articles",
"items" => ("one" => "Iteration","two" => "Recursion",
"methods" => ("factorial" => "Recursion","fibonacci" => "Recursion"),)
"parent"? => "Larry Ullman",
);
var_dump
(
find_in_arr('two', $arr),
find_in_arr('parent', $arr),
find_in_arr('fibonacci', $arr)
//find_in_arr('name', $arr),
//find_in_arr('subject', $arr),
//find_in_arr('type', $arr)
);

It should be:
$arr = array(
"name" => "Php Master",
"subject" => "Php",
"type" => "Articles",
"items" => array(
"one" => "Iteration",
"two" => "Recursion",
"methods" => array(
"factorial" => "Recursion",
"fibonacci" => "Recursion"
)
),
"parent" => "Larry Ullman"
);

Related

Remove from multidimensional array if has seen id before in an basic array

I would like in php to stop duplicate messages by logging msgid to a text file using something like this file_put_contents("a.txt", implode(PHP_EOL, $array1), FILE_APPEND);
and then converting it back to an array using $array1 = file("a.txt"); I would also like to delete messages from the array if they are from a set name
I know how to convert json to an array $array1 = json_decode($json, true);
Json Reply from an api that I cannot control
{
"API": "Online",
"MSG": [
{
"info": {
"name": "example"
},
"msg": "example",
"msgid": "example"
},
{
"info": {
"name": "example"
},
"msg": "example",
"msgid": "example"
}
]
}
Hi use the following code, first test it out accordingly
$uniqueMessages = unique_multidim_array($messages,'msg');
Usage : Pass the key as the 2nd parameter for which you need to check the uniqueness of array.
<?php
/* Function to handle unique assocative array */
function unique_multidim_array($array, $key) {
/* temp array to hold unique array */
$temp_array = array();
/* array to hold */
$i = 0;
/* array to hold the key for unique array */
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$messages = array(
0 => array(
'info' => array(
'name' => 'example'
),
'msg' => 'example',
'msgid' => 'example'
),
1 => array(
'info' => array(
'name' => 'example 1'
),
'msg' => 'example 1',
'msgid' => 'example 1'
),
3 => array(
'info' => array(
'name' => 'example'
),
'msg' => 'example',
'msgid' => 'example'
)
);
echo '<pre>';
echo '*****************BEFORE***********************<br/>';
var_dump($messages);
echo '*****************AFTER***********************<br/>';
$uniqueMessages = unique_multidim_array($messages,'msg');
var_dump($uniqueMessages);
This works for me this is an modded function click here for original function
function RemoveElementByArray($array, $key, $seen){
foreach($array as $subKey => $subArray){
if(in_array($subArray[$key], $seen)){
unset($array[$subKey]);
}
}
return $array;
}
Example:
$array = array(
array("id" => "1", "name" => "example1"),
array("id" => "2", "name" => "example2"),
array("id" => "3", "name" => "example3"));
$SeenArray = array("1", "2");
print_r(RemoveElementByArray($array, "id", $SeenArray));
Result:
Array
(
[2] => Array
(
[id] => 3
[name] => example3
)
)

Search for matching subarray in parent or child of a multidimensional array

I have the following multidimensional array to build a dynamic menu:
[
"3gnitjUdm6" => [
"name" => "Overview",
"slug" => "overview",
"priority" => 1,
"pages" => [
"i3OQlLqgqO" => [
"name" => "Dashboard",
"url" => "",
"priority" => 2,
"subpages" => [],
],
"izma1tvjGd" => [
"name" => "Settings",
"url" => "/settings",
"priority" => 4,
"subpages" => [],
]
]
],
"IcSujiIx9A" => [
"name" => "Content",
"slug" => "content",
"priority" => 5,
"pages" => [
"3KJdhtCRuI" => [
"name" => "Users",
"url" => "/users",
"priority" => 2,
"subpages" => [],
],
"M3zw9hq6rW" => [
"name" => "Pets",
"url" => "/pets",
"priority" => 4,
"subpages" => [],
],
],
],
]
Each section contains an array of pages, and each page can contain an array of subpages. I need to be able to search through this array to find the key of the section using a key and value pair.
private function _find_section($key, $value) {
foreach($this->menu as $section_key => $section) {
if(is_array($section[$key])) {
foreach($section[$key] as $sub_key => $sub) {
if($sub_key === $value) {
return $section_key;
}
}
} elseif(is_string($section[$key])) {
if($section[$key] === $value) {
return $section_key;
}
} else {
return false;
}
}
}
Running the following code:
_find_section('name', 'Content')
Always returns false.
function flatten(array $collection, array $nested_keys = []) {
$output = [];
foreach ($collection as $key => $value) {
foreach ($nested_keys as $nested_key) {
if (isset($value[$nested_key]) && is_array($value[$nested_key])) {
$output = array_merge($output, flatten($value[$nested_key], [$nested_key]));
}
}
$output[$key] = $value;
}
return $output;
}
function column(array $collection, string $key) {
return array_combine(
array_keys($collection),
array_map(function ($row) use ($key) { return $row[$key]; }, $collection)
);
}
function find_section(array $menu, string $key, string $value) {
$set = column(flatten($menu, ['pages', 'subpages']), $key);
return array_search($value, $set);
}
var_dump(find_section($menu, 'name', 'Dashboard')); // string(10) "i3OQlLqgqO"
You might want to try doing a recursive function instead and forego hardcoded foreach() loops, then you can easily search through many levels of your array using this method:
function recurseFind($array,$findK,$findV,$last=false)
{
if(is_object($array))
$array = (array) $array;
foreach($array as $key => $value) {
if($key == $findK && $value == $findV)
return $last;
if(is_array($value))
$doFind = recurseFind($value,$findK,$findV,$key);
if(!empty($doFind))
return $doFind;
}
}
print_r(recurseFind($arr,'name','Dashboard'));
Gives you:
i3OQlLqgqO

Remove duplicates from a multidimensional array based on multiple keys

Sorry if this was asked before, but I searched a lot and couldn't find a solution.
I've been trying to solve this problem for a while now, and couldn't write the function for it.
I have an array like that:
$numbers = array(
array("tag" => "developer", "group" => "grp_1", "num" => "123123"),
array("tag" => "developer", "group" => "grp_2", "num" => "111111"),
array("tag" => "student", "group" => "grp_1", "num" => "123123"),
array("tag" => "student", "group" => "grp_2", "num" => "123123"),
array("tag" => "developer", "group" => "grp_3", "num" => "111111"),
);
I need to write a function, that removes the duplicates off this array, based on multiple keys, so my function call should look something like that:
unique_by_keys($numbers, array("num","group"));
In other terms, one number can't be in the same group more than once.
After calling unique_by_keys() by array should be like that:
$numbers = array(
array("tag" => "developer", "group" => "grp_1", "num" => "123123"),
array("tag" => "developer", "group" => "grp_2", "num" => "111111"),
array("tag" => "student", "group" => "grp_2", "num" => "123123"),
array("tag" => "developer", "group" => "grp_3", "num" => "111111"),
);
I'd appreciate if you could help me find a solution, or lead me to the correct way of thinking.
Thanks!
SOLUTION:
I was able to find a solution, by writing the following function:
( I wrote it in a way that accepts many forms of $haystack arrays )
function unique_by_keys($haystack = array(), $needles = array()) {
if (!empty($haystack) && !empty($needles)) {
$_result = array();
$result = array();
$i = 0;
foreach ($haystack as $arrayObj) {
if (is_array($arrayObj)) {
$searchArray = array();
foreach ($needles as $needle) {
if (isset($arrayObj[$needle])) {
$searchArray[$needle] = $arrayObj[$needle];
}
}
if (!in_array($searchArray, $_result)) {
foreach ($arrayObj as $key => $value) {
if (in_array($key, $needles)) {
$_result[$i][$key] = $value;
}
}
$result[] = array_merge($_result[$i], $arrayObj);
}
} else {
$result[] = $arrayObj;
}
$i++;
}
return $result;
}
}
Thanks for everyone that replied!
Bhaskar's approach which assigns unique keys in the loop to remove duplicates affords a very small function for this case.
Here is a previous and unnecessarily complicated version:
function unique_by_keys($haystack=array(),$needles=array()){
// reverse order of sub-arrays to preserve lower-indexed values
foreach(array_reverse($haystack) as $row){
$result[implode('',array_intersect_key($row,array_flip($needles)))]=$row; // assign unique keys
}
ksort($result); // sort the sub-arrays by their assoc. keys
return array_values($result); // replace assoc keys with indexed keys
}
This is the best/leanest solution I can come up with:
$numbers = array(
array("tag" => "developer", "group" => "grp_1", "num" => "123123"),
array("tag" => "developer", "group" => "grp_2", "num" => "111111"),
array("tag" => "student", "group" => "grp_1", "num" => "123123"),
array("tag" => "student", "group" => "grp_2", "num" => "123123"),
array("tag" => "developer", "group" => "grp_3", "num" => "111111")
);
function unique_by_keys($haystack=array(),$needles=array()){
foreach($haystack as $row){
$key=implode('',array_intersect_key($row,array_flip($needles))); // declare unique key
if(!isset($result[$key])){$result[$key]=$row;} // save row if non-duplicate
}
return array_values($result);
}
echo "<pre>";
var_export(unique_by_keys($numbers,array("group","num")));
echo "</pre>";
Output:
array (
0 =>
array (
'tag' => 'developer',
'group' => 'grp_1',
'num' => '123123',
),
1 =>
array (
'tag' => 'developer',
'group' => 'grp_2',
'num' => '111111',
),
2 =>
array (
'tag' => 'student',
'group' => 'grp_2',
'num' => '123123',
),
3 =>
array (
'tag' => 'developer',
'group' => 'grp_3',
'num' => '111111',
),
)
$newNumbers = array();
foreach($numbers as $key=>$values){
$newkey = $values['group'].'__'.$values['num'];
$newNumbers[$newkey] = $values;
}
var_dump($newNumbers)
Code might not be efficient, but i will work for you :)
$result = unique_by_keys($numbers, array("num","group"));
echo "<pre>";
print_R($result);
function unique_by_keys($numbers, $arr){
$new_array = array();
$output = array();
foreach ($numbers as $n){
if(isset($new_array[$n[$arr[1]]]) && $new_array[$n[$arr[1]]] == $n[$arr[0]]){
continue;
}else{
$new_array[$n[$arr[1]]] = $n[$arr[0]];
$output[] = $n;
}
}
return $output;
}

Compare Dynamic Multidimensional Arrays

I have two multidimensional dynamic arrays like so in PHP:
$old = array(
"meta_data" => array(
"page_title" => "Test1",
"page_description" => "Test2",
"page_keywords" => "Test3"
),
"content" => array(
"page_header_one" => "1",
"page_content_one" => "2",
"page_header_two" => "3",
"page_content_two" => "4",
"page_header_three" => "5"
),
);
$new = array(
"meta_data" => array(
"page_title" => "Test1",
"page_description" => "Test2",
"page_keywords" => "Test3324"
),
"content" => array(
"page_header_one" => "124",
"page_content_one" => "243",
"page_header_two" => "343"
),
);
I'm struggling to compare these as they're dynamic, e.g. the keys change. What I'm aiming to do is compare the arrays, find out what's changed, leave out keys that don't match, and only add the changes to the new array.
The only things that will be constant are "meta_data" and "content"
So for example in $old we have 5 items in the content array, but in the $new array we only have 3 items (3 changed items), so the new array would have 3 content items.
Is there a way to do this I can't for the life in me figure out how?
Final array should look like so:
$final = array(
"meta_data" => array(
"page_keywords" => "Test3324"
),
"content" => array(
"page_header_one" => "124",
"page_content_one" => "243",
"page_header_two" => "343"
),
);
Maybe it can be done easier, but I think this will do the job:
<?php
$newArray = [];
foreach($old['meta_data'] as $key => $value) {
if(array_key_exists($key, $new['meta_data'])) {
if($new['meta_data'][$key] == $old['meta_data'][$key]) {
$newArray['meta_data'][$key] = $value;
}
}
}
foreach($old['content'] as $key => $value) {
if(array_key_exists($key, $new['content'])) {
if($new['content'][$key] == $old['content'][$key]) {
$newArray['content'][$key] = $value;
}
}
}
You can also make the top key dynamic, so content and meta_data are dynamic as well, like this:
foreach($old as $topKey => $subArray) {
if(array_key_exists($topKey, $new)) {
foreach($subArray as $key => $value) {
if(array_key_exists($key, $new[$topKey])) {
if($new[$topKey][$key] == $old[$topKey][$key]) {
$newArray[$topKey][$key] = $value;
}
}
}
}
}
I haven't tested it. But I think you'll get the gist.
The only things that will be constant are "meta_data" and "content"
Given this thing in mind, the solution to your problem would be to use array_diff() function like this:
$final = array();
$final['meta_data'] = array_diff($new['meta_data'], $old['meta_data']);
$final['content'] = array_diff($new['content'], $old['content']);
// display $final array
var_dump($final);
Here's a live demo
You can simply use the PHP array_diff() function.
$final = array_diff($new, $old);

Not getting array all values using php

I have this following array
$question = array(
"ques_15" => array(
"name" => array(
"0" => "aaa"
)
),
"ques_16" => array(
"name" => array(
"0" => "bbb",
"1" => "ccc"
)
)
);
$i=0;
foreach($question as $k=>$v)
{
echo $question[$k]['name'][$i];
$i++;
}
But my output is only
aaaccc
I am missing the value bbb
You need to iterate the inner 'name' arrays - you could use a nested foreach loop:
$question = array(
"ques_15" => array(
"name" => array(
"0" => "aaa"
)
),
"ques_16" => array(
"name" => array(
"0" => "bbb",
"1" => "ccc"
)
)
);
foreach($question as $quest)
{
foreach($quest['name'] as $val)
{
echo $val;
}
}
you should loop though like so
foreach($question as $q)
{
foreach($q['name'] as $v)
{
echo $v;
}
}
in foreach you don't need a counter $i, it's for while() or for()
you array is two dimensional so you need 2 foreach
Check it out in a functional way.
The shorthand array declaration works only on PHP 5.4+ though, but it still works with your longhand array declaration.
$questions = [
'ques_15' => ['name' => ['aaa']],
'ques_16' => ['name' => ['bbb', 'ccc']]
];
array_map(function($a){
foreach ($a['name'] as $v) echo $v;
}, $questions);

Categories