I have the following code:
$a=array(15,12,13,25,27,36,18);
$b=array(1,1,1,1,1,1,1);//is it possible to pass only one value=1, instead of array containing seven 1's
// expectation: $b = array(1); or $b= 1;
//instead of $b=array(1,1,1,1,1,1,1);
function array_add($p,$q){
return($p+$q);
}
$c=array_map("array_add",$a,$b);
I want something like:
$a=array(15,12,13,25,27,36,18);
$b=array(1);
function array_add($p,$q){
return($p+$q);
}
$c=array_map("array_add",$a,$b);
Any better solution thanks.
You can use array_map as this, and pass the $param2 with use()
array_map(function($v) use($param2){
//do something
}, $input);
Have a look at array_walk
From Your example, it would be:
function array_add( &$item, $key, $toAdd) {
$item+=$toAdd;
}
array_walk($a, 'array_add', 1);
I would also recommend that you have a look at the answer provided using closure(use)
Related
I am building a recursive function, which executes any function for any-deep-nested-array. For example, I want to STRIPSLASH all array values in this:
function RECURSER($array,$function_name){
return is_array($array) ? array_map('RECURSER', $array, $function_name) : $function_name($array);
}
but when I execute:
recursive_for_array_value( $MY_ARRAY, 'stripslashes')
the above function can't send second parameter to array_map.
Now I'll start off by saying that I'd probably never use this in any real projects, but this is an interesting challenge/question and T.Todua's answer works but using $GLOBALS can be avoided.
My position is that array_walk_recursive() is a better suited function versus recursively calling array_map() -- after all, array_walk_recursive() was specifically designed to visit leaf nodes and avoid the tedium of checking the current item's type as "array". use() is effective in passing the function string into the recursive function's scope.
*Note: You could only pass the function string as a string in a SUPER fringe case where the function prints to screen AND requires two arguments -- the first arg being the element value and the second arg being the element key.
Because you want to only process the element values AND modify them by reference, &$v is necessary.
Here is a relevant post to read regarding checking the dynamic function name: What exactly is the difference between the is_callable and function_exists in PHP?
Here is my working alternative:
Code: (Demo)
$multidim_array = ['a' => [' \one ', ['b' => 'two\\', [['c' => 'thr\ee']]]]];
$func = 'stripslashes';
if (function_exists($func)) {
array_walk_recursive($multidim_array, function(&$v)use($func){$v = $func($v);});
var_export($multidim_array);
} else {
echo "not callable";
}
If you wanted to go down this rabbit hole further, you could extend its potential utility by setting up the option to pass multiple arguments:
Code: (Demo)
$func = 'strpos';
if (function_exists($func)) {
$more = true;
$param2 = 'o';
array_walk_recursive($multidim_array, function(&$v)use($func, $more, $param2) {
if ($more) {
$v = $func($v, $param2);
} else {
$v = $func($v);
}
});
var_export($multidim_array);
} else {
echo "um... I'm not calling $func";
}
Finally, the approach that I whole-heartedly do NOT endorse is the use of eval() -- because you can see the tail, horns, and pitchfork a mile away.
Caution
The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.
This works, but really should not be entertained:
if (function_exists($func)) {
array_walk_recursive($multidim_array, function(&$v)use($func) {eval("\$v = $func(\$v);"); });
var_export($multidim_array);
} else {
echo "um... I'm not calling $func";
}
RECURSOR of any function:
$result= Recursiver_of_Array($array, 'stripslashes');
code:
function Recursiver_of_Array($array,$function_name=false){
if ($function_name) { $GLOBALS['current_func_name']= $function_name; }
return is_array($array) ? array_map('Recursiver_of_Array', $array) : $GLOBALS['current_func_name']($array);
}
array_map accepts one function and multiple arrays as arguments. Perhaps you need to recursively call recurser via an anonymous function instead.
function RECURSER($array,$function_name){
if (is_array($array))
return array_map(function ($element) use ($function_name) {
return RECURSER($element,$function_name);
},$array);
return $function_name($array);
}
The usecase of stripslashes as a one-line PHP function can be written as :
array_walk_recursive($array, function (&$value) { $value = stripslashes($value); });
I have a function and I need it to return two arrays.
I know a function can only return one variable .. is there a way to return my two arrays?
If I concatenate them, how can I separate them cleanly when out of the function?
No need to concatenate: just return array of two arrays, like this:
function foo() {
return array($firstArray, $secondArray);
}
... then you will be able to assign these arrays to the local variables with list, like this:
list($firstArray, $secondArray) = foo();
And if you work with PHP 5.4, you can use array shortcut syntax here as well:
function foo54() {
return [$firstArray, $secondArray];
}
I think raina77ow's answer adequately answers your question. Another option to consider is to use write parameters.
function foobar(array &$arr1 = null)
{
if (null !== $arr1) {
$arr1 = array(1, 2, 3);
}
return array(4, 5, 6);
}
Then, to call:
$arr1 = array();
$arr2 = foobar($arr1);
This won't be useful if you always need to return two arrays, but it can be used to always return one array and return the other only in certain cases.
In short, I have a function like the following:
function plus($x, $y){
echo $x+$y;
}
I want to tell the function its parameters as array like the following:
$parms = array(20,10);
plus($parms);
But unfortunately, not work.
I'm tired by using another way as the following:
$parms = array(20,10);
$func_params = implode(',', $parms);
plus($func_params);
And also not work, and gives me Error message:
Warning: Missing argument 2 for plus(), called in.....
And now, I'm at a puzzled.
What can I do to work ?
There is a couple things you can do.
Firstly, to maintain your function definition you can use call_user_func_array(). I think this is ugly.
call_user_func_array('plus', $parms);
You can make your function more robust by taking a variable number of params:
function plus(){
$args = func_get_args();
return $args[0] + $args[1];
}
You can simply accept an array and add everything up:
function plus($args){
return $args[0] + $args[1];
}
Or you could sum up all arguments:
function plus($args){
return array_sum($args);
}
This is PHP, there are 10 ways to do everything.
You need to adapt your function so that it only accepts one parameter and then in the function itself, you can process that parameter:
Very simple example:
function plus($arr){
echo $arr[0]+$arr[1];
}
$parms = array(20,10);
plus($parms);
You can easily adapt that to loop through all elements, check the input, etc.
Heh? The error message is very clear: you ask for two parameters in your function, but you only provide one.
If you want to pass an array, it would be a single variable.
function plus($array){
echo ($array[0]+$array[1]);
}
$test = array(1,5);
plus($test); //echoes 6
Use this:
function plus($arr){
$c = $arr[0]+$arr[1];
echo $c;
}
And the you can invoke:
$parms = array(20,10);
plus($parms);
I have really simple problem in my PHP script. There is a function defined which takes variable length argument list:
function foo() {
// func_get_args() and similar stuff here
}
When I call it like this, it works just fine:
foo("hello", "world");
However, I have my variables in the array and I need to pass them "separately" as single arguments to the function. For example:
$my_args = array("hello", "world");
foo(do_some_stuff($my_args));
Is there any do_some_stuff function which splits the arguments for me so I can pass them to the function?
Use
ReflectionFunction::invokeArgs(array $args)
or
call_user_func_array( callback $callback, array $param_arr)
Well you need call_user_func_array
call_user_func_array('foo', $my_args);
http://php.net/manual/en/function.call-user-func-array.php
You are searching for call_user_func_array().
http://it2.php.net/manual/en/function.call-user-func-array.php
Usage:
$my_args = array("hello", "world");
call_user_func_array('foo', $my_args);
// Equivalent to:
foo("hello", "world");
Sounds to me like you are looking for call_user_func_array.
http://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list
Isn't this what you want?
edit
ah... ok... how about this:
Passing an Array as Arguments, not an Array, in PHP
If you can change the code of foo() it should be easy to solve this in just one place.
function foo()
{
$args = func_get_args();
if(count($args) == 1 && is_array($args[0]))
{
$args = $args[0]
}
// use $args as normal
}
This solution is not recommended at all, but just showing a possibility :
Using eval
eval ( "foo('" . implode("', '", $args_array) . "' )" );
I know it's an old question but it still comes up as the first search result - so here is an easier way;
<?php
function add(... $numbers) {
$result=0;
foreach($numbers as $number){
$result+=intval($number);
}
return $result;
}
echo add(...[1, 2])."\n";
$a = [1, 2];
echo add(...$a);
?>
Source:
https://www.php.net/manual/en/functions.arguments.php#example-142
any idea how if the following is possible in PHP as a single line ?:
<?php
$firstElement = functionThatReturnsAnArray()[0];
... It doesn't seem to 'take'. I need to do this as a 2-stepper:
<?php
$allElements = functionThatReturnsAnArray();
$firstElement = $allElements[0];
... just curious - other languages I play with allow things like this, and I'm lazy enoug to miss this in PHP ... any insight appreciated ...
#Scott Reynen
that's not true. This will work:
list(,,$thirdElement) = $myArray;
Try:
<?php
$firstElement = reset(functionThatReturnsAnArray());
If you're just looking for the first element of the array.
Unfortunately, that is not possible with PHP. You have to use two lines to do it.
You can do this in one line! Use array_shift().
<?php
echo array_shift(i_return_an_array());
function i_return_an_array() {
return array('foo', 'bar', 'baz');
}
When this is executed, it will echo "foo".
list() is useful here. With any but the first array element, you'll need to pad it with useless variables. For example:
list( $firstElement ) = functionThatReturnsAnArray();
list( $firstElement , $secondElement ) = functionThatReturnsAnArray();
And so on.
I actually use a convenience function i wrote for such purposes:
/**
* Grabs an element from an array using a key much like array_pop
*/
function array_key_value($array, $key) {
if(!empty($array) && array_key_exists($key, $array)) {
return $array[$key];
}
else {
return FALSE;
}
}
then you just call it like so:
$result = array_key_value(getMeAnArray(), 'arrayKey');
You can use array_slice(), like so:
$elementX = array_slice(functionThatReturnsAnArray(), $x, 1);
Also noticed that end() is not mentioned. It returns the last element of an array.
Either current($array) or array_shift($array) will work, the former will leave the array intact.
nickf, good to know, thanks. Unfortunately that has readability problems beyond a few commas.
I think any of the above would require a comment to explain what you're doing, thus becoming two lines. I find it simpler to do:
$element = functionThatReturnsArray();
$element = $element[0];
This way, you're not using an extra variable and it's obvious what you're doing.
$firstItem = current(returnsArray());
Well, I have found a couple of ways to get what you want without calling another function.
$firstElement = ($t = functionThatReturnsAnArray()) ? $t[0] : false;
and for strings you could use
$string = (($t = functionThatReturnsAnArray())==0) . $t[0];
.. Interesting problem
Draco
I am guessing that this is a built-in or library function, since it sounds like you cannot edit it directly. I recommend creating a wrapper function to give you the output you need:
function functionThatReturnsOneElement( $arg )
{
$result = functionThatReturnsAnArray( $arg );
return $result[0];
}
$firstElement = functionThatReturnsOneElement();
As far as I know this is not possible, I have wanted to do this myself several times.
http://us3.php.net/reset
Only available in php version 5.
If it's always the first element, you should probably think about having the function return just the first item in the array. If that is the most common case, you could use a little bit of coolness:
function func($first = false) {
...
if $first return $array[0];
else return $array;
}
$array = func();
$item = func(true);
My php is slightly rusty, but i'm pretty sure that works.
You can also look at array_shift() and array_pop().
This is probably also possible:
array(func())[0][i];
The 0 is for the function.
Sometimes I'll change the function, so it can optionally return an element instead of the entire array:
<?php
function functionThatReturnsAnArray($n = NULL) {
return ($n === NULL ? $myArray : $myArray[$n]);
}
$firstElement = functionThatReturnsAnArray(0);