Function only returns first array - php

I'm trying to add some settings to my WordPress options page that depend on the number of categories. I created this function to use inside the main array, but it only returns the first array, leaving out the other 3 I have. A print_r will show all of them, so I can't seem to figure this out.
function listSections() {
$categories = get_categories();
foreach($categories as $category) {
return array (
"name" => $category->cat_name . " Label Color",
"desc" => "Select a label color.",
"id" => $shortname."_label_color" . $category->cat_ID,
"type" => "select",
"options" => $color_options,
"std" => ""
);
}
}

You can only return once!
function listSections() {
$categories = get_categories();
$return = array();
foreach($categories as $category) {
$return[] = array (
"name" => $category->cat_name . " Label Color",
"desc" => "Select a label color.",
"id" => $shortname."_label_color" . $category->cat_ID,
"type" => "select",
"options" => $color_options,
"std" => ""
);
}
return $return;
}
The fix is push each array into a temporary array, then return that array at the end of the loop.

The function can only return once. It cannot return multiple things in a loop. After it reaches the first return, it exits the function completely. If you want to return an array of arrays, you should use the following.
function listSections() {
$results = array();
$categories = get_categories();
foreach($categories as $category) {
$results[] = array (
"name" => $category->cat_name . " Label Color",
"desc" => "Select a label color.",
"id" => $shortname."_label_color" . $category->cat_ID,
"type" => "select",
"options" => $color_options,
"std" => ""
);
}
return $results;
}
using the syntax $result[] = xyz; will append xyz to the end of the array. You can loop through the returned array, with some code like
$results = listSections();
$count = count($results);
for ($i = 0; $i < $count; $i++) {
$category = $results[$i];
echo $category["name"];
etc......
}

When you call return from a function it always immediately ends the execution of that function, so as soon as the first array gets returned, the function ends - which is why you are only getting the first array back.
You could try returning a multi-dimensional array (an array that contains all of the arrays you'd like to be returned) instead.

The goal of the returnkeyword is to exit the function. So it is normal that your fonction only return the first element.
You can for exemple put all the elements into an array and return this array :
function listSections() {
$categories = get_categories();
$arr = array();
foreach($categories as $category) {
$arr[] = array (
"name" => $category->cat_name . " Label Color",
"desc" => "Select a label color.",
"id" => $shortname."_label_color" . $category->cat_ID,
"type" => "select",
"options" => $color_options,
"std" => ""
);
}
return $arr;
}

Related

php array: if identical key values then choose highest by other key value

$myArray = [
"ID" => "",
"Module" => "",
"Version"=> ""
];
Output:
[
{23,finance,1.0},
{24,finance,1.1},
{25,logistic,1.0}
]
I have an array with the given Keys like above. I need a new array that gives me the highest Version IF module is same. How would I do that?
desired Output:
[
{24,finance,1.1},
{25,logistic,1.0}
]
This is what I tried
$modulesFiltered = [];
$i = 0;
$j = 0;
foreach($modules as $module){
$modulesFiltered[$i]['ID'] = $module['ID'];
foreach($modulesFiltered as $moduleF){
if(!empty($moduleF[$j]['Module'])){
if($module[$i]['Module'] == $moduleF[$j]['Module']){
$modulesFiltered[$i]['Module'] = 'this is doubled';
}
} else {
$modulesFiltered[$i]['Module'] = $module['Module'];
}
$j++;
}
$modulesFiltered[$i]['Module'] = $module['Module'];
$i++;
}
I tried to debug your code though.The problem is that you try to access element [0] of $moduleF. You should change $moduleF[$j]['Module'] to $moduleF['Module'].
Use standard functions where possible. for finding values within (multidimensional) array's you can use array_search. The code beneath works.
Also don't compare strings with == use strcmp(str1, str2) == 0 instead
$inputArray = array(
array(
"ID" => 23,
"Module" => "finance",
"Version"=> 1.0),
array(
"ID" => 24,
"Module" => "finance",
"Version"=> 1.1),
array(
"ID" => 25,
"Module" => "logistiscs",
"Version"=> 1.0));
$output = array();
foreach($inputArray as $element)
{
$key = array_search($element["Module"], array_column($output, "Module"));
if(is_numeric($key))
$output[$key]["Version"] = max($element["Version"], $output[$key]["Version"]);
else
$output[] = $element;
}
print_r($output);

PHP adding values inside multidimensional array

Please find below the code sample for adding repeated values inside inner array. Can anyone suggest an alternative way to add the values faster? The code will work with smaller arrays, but I want to add big arrays that contain huge amount of data. Also I want to increase execution time.
<?php
$testArry = array();
$testArry[0] = array(
"text" => "AB",
"count" => 2
);
$testArry[1] = array(
"text" => "AB",
"count" => 5
);
$testArry[2] = array(
"text" => "BC",
"count" => 1
);
$testArry[3] = array(
"text" => "BD",
"count" => 1
);
$testArry[4] = array(
"text" => "BC",
"count" => 7
);
$testArry[5] = array(
"text" => "AB",
"count" => 6
);
$testArry[6] = array(
"text" => "AB",
"count" => 2
);
$testArry[7] = array(
"text" => "BD",
"count" => 111
);
$match_key = array();
$final = array();
foreach ($testArry as $current_key => $current_array) {
$match_key = array();
foreach ($testArry as $search_key => $search_array) {
$key = '';
if ($search_array['text'] == $current_array['text']) {
$match_key[] = $search_key;
$key = $search_array['text'];
if (isset($final[$key])) {
$final[$key] += $search_array['count'];
} else {
$final[$key] = $search_array['count'];
}
}
}
for ($j = 0; $j < count($match_key); $j++) {
unset($testArry[$match_key[$j]]);
}
}
print_r($final);
?>
Anyway to add memory during the execution time?
Thank you.
One array_walk will be enough to solve your problem,
$final = [];
array_walk($testArry, function($item) use(&$final){
$final[$item['text']] = (!empty($final[$item['text']]) ? $final[$item['text']] : 0) + $item['count'];
});
print_r($final);
Output
Array
(
[AB] => 15
[BC] => 8
[BD] => 112
)
Demo
array_walk — Apply a user supplied function to every member of an array
array_map() - Applies the callback to the elements of the given arrays
array_key_exists() - Checks if the given key or index exists in the array
You can use array_walk and array_key_exists to iterate through the array element and sum the one which has text index same
$res = [];
array_map(function($v) use (&$res){
array_key_exists($v['text'], $res) ? ($res[$v['text']] += $v['count']) : ($res[$v['text']] = $v['count']);
}, $testArry);

Unset is not unsetting Array values

I am trying to build a dynamic Menu from data I generate from jstree.
Jstree values will stored in database as follows:
Id | Name | Parent | Icon | Link
So I've made a method to read each row from database(propel) and store it in array, so Smarty can build a menu dynamically.
That's my function:
$menu_content = array();
foreach($result as $key => $r) {
if($r['Id'] != 1) {
$Id = $r['Id'];
$menu_content[$r['Id']] = array(
"name" => $r['Name'],
"link" => $r['Link'],
"icon" => $r['Icon']
);
unset($result[$key]);
foreach($result as $key_children => $c) {
if($c['Parent'] == $r['Id']) {
$menu_content[$r['Id']]['children'][] = array(
"name" => $c['Name'],
"link" => $c['Link'],
"icon" => $c['Icon']
);
unset($result[$key_children]);
$Idc = $c['Id'];
foreach($result as $key_grandchild => $cc) {
if($cc['Parent'] == $c['Id']) {
$menu_content[$r['Id']]['children']['grandchild'][] = array(
"name" => $cc['Name'],
"link" => $cc['Link'],
"icon" => $cc['Icon']
);
unset($result[$key_grandchild]);
}
}
}
}
}
So it should store values like this:
$menu_content[parent][children][grandchildren].
This part of code is working fine, but it's not unsetting the children and grandchildren values, so I get them twiche. First time in correct order and after that as parent children.
Thanks in advance.

Sorting Array not working correctly

The sorting of array in alphabetical order is not outputting correctly.
It outputted as:
Demo
qwerty
Demo3
Test1
Test2
New1
Instead of:
Demo
Demo3
New1
qwerty
Test1
Test2
Code:
<?php
$dbresults= array ( "0" => array ( "id" => "1",
"cb_boutiquename1" => "Test1",
"cb_boutiquename2" => "Test2",
"cb_boutiquename3" => "New1"
),
"1" => array ( "id" => "2",
"cb_boutiquename1" => "Demo",
"cb_boutiquename2" => "qwerty",
"cb_boutiquename3" => "Demo3"
)
);
function sortarray($a, $b) {
return strcmp($a["cb_boutiquename$i"], $b["cb_boutiquename$i"]);
}
usort($dbresults, "sortarray");
while (list($key, $value) = each($dbresults)) {
$results[] = $value ;
}
foreach($results as $result) {
$i = 1;
while (array_key_exists("cb_boutiquename$i", $result)) {
if ($result["cb_boutiquename$i"] !='') {
echo '<a href=' . cbSef( 'index.php?option=com_comprofiler&task=page&user=' . (int) $result['id'] . '&b=' . $i . getCBprofileItemid( false )) . '>' . $result["cb_boutiquename$i"] . '</a><br />';
}
++$i;
}
}
?>
Your problem is that in here:
function sortarray($a, $b) {
return strcmp($a["cb_boutiquename$i"], $b["cb_boutiquename$i"]);
}
$i is undefined so you are basically comparing one undefined array offset with another.
If you want to specify which of the cb_boutiquename fields to specify at runtime then what you probably want to do is include the $i in the function, on php this can be done with a function that returns a closure (PHP 5.3+).
function getSorter($idx){
return function($a, $b) use ($idx) {
return strcmp($a["cb_boutiquename$idx"], $b["cb_boutiquename$idx"]);
};
}
This returns a function that closes over the supplied argument and is appropriate for use as a comparison function for usort. So for your sort call you would use:
usort($dbresults, getSorter(1));
Or for a more general solution that does not assume the cb_boutiquename prefix on the properties you can change this to
function getSorter($idx){
return function($a, $b) use ($idx) {
return strcmp($a[$idx], $b[$idx]);
};
}
usort($dbresults, getSorter("cb_boutiquename1"));
This will allow you to sort any array of arrays by an one of the indexes.
UPDATE
I completely misunderstood the goal of this exercise. What you want to do is to flatten your array prior to doing any sorting.
$dbresults= array ( "0" => array ( "id" => "1",
"cb_boutiquename1" => "Test1",
"cb_boutiquename2" => "Test2",
"cb_boutiquename3" => "New1"
),
"1" => array ( "id" => "2",
"cb_boutiquename1" => "Demo",
"cb_boutiquename2" => "qwerty",
"cb_boutiquename3" => "Demo3"
)
);
// flatten out the array
$results = array();
foreach($dbresults as $k=>$v){
foreach ($v as $key=>$value) {
if (substr($key, 0,15) == "cb_boutiquename"){
$results[] = array("id"=>$v["id"], "cb_boutiquename"=>$value, "i"=>substr($key, 15));
}
}
}
usort($results, function($a, $b){ return strcasecmp($a["cb_boutiquename"], $b["cb_boutiquename"]); });
foreach($results as $result){
echo '<a href=' . cbSef( 'index.php?option=com_comprofiler&task=page&user=' . (int) $result['id'] . '&b=' . $result["i"] . getCBprofileItemid( false )). '>' . $result["cb_boutiquename"] . '</a><br />'."\n";
}
Instead of your sortarray function, use simply this:
asort($dbresults);
No need to reinvent the wheel. Read about it here

Dynamic array key in while loop

I'm trying to get this working:
I have an array that gets "deeper" every loop. I need to add a new array to the deepest "children" key there is.
while($row = mysql_fetch_assoc($res)) {
array_push($json["children"],
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
}
So, in a loop it would be:
array_push($json["children"] ...
array_push($json["children"][0]["children"] ...
array_push($json["children"][0]["children"][0]["children"] ...
... and so on. Any idea on how to get the key-selector dynamic like this?
$selector = "[children][0][children][0][children]";
array_push($json$selector);
$json = array();
$x = $json['children'];
while($row = mysql_fetch_assoc($res)) {
array_push($x,
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
$x = $x[0]['children'];
}
print_r( $json );
Hmmm - maybe better to assign by reference:
$children =& $json["children"];
while($row = mysql_fetch_assoc($res)) {
array_push($children,
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
$children =& $children[0]['children'];
}
$json = array();
$rows = range('a', 'c');
foreach (array_reverse($rows) as $x) {
$json = array('id' => $x, 'name' => 'start', 'children' => array($json));
}
print_r($json);
If you want to read an array via a string path, split the string in indices, and then you can do something like this to get the value
function f($arr, $indices) {
foreach ($indices as $key) {
if (!isset($arr[$key])) {
return null;
}
$arr = $arr[$key];
}
return $arr;
}

Categories