Passing object method to array_map() [duplicate] - php

This question already has answers here:
How to use class methods as callbacks
(5 answers)
Closed 3 months ago.
class theClass{
function doSomeWork($var){
return ($var + 2);
}
public $func = "doSomeWork";
function theFunc($min, $max){
return (array_map(WHAT_TO_WRITE_HERE, range($min, $max)));
}
}
$theClass = new theClass;
print_r(call_user_func_array(array($theClass, "theFunc"), array(1, 5)));
exit;
Can any one tell what i can write at WHAT_TO_WRITE_HERE, so that doSomeWork function get pass as first parameter to array_map. and code work properly.
And give out put as
Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
[4] => 7
)

To use object methods with array_map(), pass an array containing the object and the objects method name. For same-object scope, use $this as normal. Since your method name is defined in your public $func property, you can pass func.
As a side note, the parentheses outside array_map() aren't necessary.
return array_map( [$this, 'func'], range($min, $max));

The following code provides an array of emails from an $users array which contains instances of a class with a getEmail method:
if(count($users) < 1) {
return $users; // empty array
}
return array_map(array($users[0], "getEmail"), $users);

I tried search for solution but it not works, so I created custom small map function that will do the task for 1 variable passed to the function it simple but will act like map
class StyleService {
function check_css_block($str){
$check_end = substr($str,-1) == ';';
$check_sprator = preg_match_all("/:/i", $str) == 1;
$check_sprator1 = preg_match_all("/;/i", $str) == 1;
if ( $check_end && $check_sprator && $check_sprator1){
return $str;
} else {
return false;
}
}
function mymap($function_name, $data){
$result = array();
$current_methods = get_class_methods($this);
if (!in_array($function_name, $current_methods)){
return False;
}
for ($i=0; $i<count($data); $i++){
$function_result = $this->{$function_name}($data[$i]);
array_push($result, $function_result);
}
return $result;
}
function get_advanced_style_data($data)
{
return $this->mymap('check_css_block', $data);
}
}
this way you can call a function name as string $this->{'function_name'}() in php

Related

How to write a function that could be called like func(a)(b)(c) in php?

I need to realize function "calc" that works like that:
$sum = function($a, $b) { return $a + $b; };
calc(5)(3)(2)($sum); // 10
calc(1)(2)($sum); // 3
calc(2)(3)('pow'); // 8
I can write something like this:
function calc(){;
print_r(func_get_args());
return __FUNCTION__;
}
calc(3)(5)(2)('sum');
and it print Array ( [0] => 3 ) Array ( [0] => 5 ) Array ( [0] => 2 ) Array ( [0] => sum ).
So, when I get 'sum' in my function, i should have an array with all previous arguments.
But i have no idea, how can i pass current argument in next function call to manipulate all of them on last iteration. Or is there some sort of recursive solution?
What you're talking about is called Currying. The following code will require PHP 7, since it involves invoking a function returned from another one, which wasn't possible until PHP's Abstract Syntax Tree was implemented in that version.
First things first, you'll need a new sum() function that can operate on an arbitrary number of variables:
$sum = function(...$args) { return array_sum($args); };
Secondly, the important part. A function that returns a new anonymous function, accumulating the arguments as it goes. When you finally pass it something callable (either your $sum function, or a built-in function name like pow), it'll execute it, unpacking the arguments that it's built up.
function calc($x)
{
return function($y = null) use ($x)
{
if (is_callable($y)) {
return $y(...$x);
} else {
$args = (array) $x;
$args[] = $y;
return calc($args);
}
};
}
echo calc(5)(3)(2)($sum); // 10
echo calc(1)(2)($sum); // 3
echo calc(2)(3)('pow'); // 8
See https://3v4l.org/r0emm
(Note that internal functions will be limited to operating on the number of arguments they are defined to take - calc(2)(3)(4)('pow') will raise an error.)
This isn't a particularly common pattern to use (which is probably why you've found it hard to track down), so please for everyone who reads it's sake, think carefully about where you use it.
Credit to the curryAdd answer in this question for the starting blocks.
Edit: I stand corrected, you don't require globals it seems! Definitely use the #iainn's answer over this one.
So to achieve this you're going to have to use globals if you're not doing it within a class to maintain current state. You can see a working example of the below code here (note that it only works for PHP version 7 and above)
<?php
$sum = function(...$args) {
return array_sum($args);
};
function calc(...$args) {
global $globalArguments;
if (is_callable($args[0])) {
$callback = $args[0];
$arguments = array_map(function ($arg) {
return $arg[0];
}, $globalArguments);
return $callback(...$arguments);
}
$globalArguments[] = $args;
return __FUNCTION__;
}
echo calc(3)(2)($sum); // 5
I don't know why you want to do this, but I don't suggest it in production, globals aren't something that should really be used if you can avoid it.
function calc(int $value, Callable $function = null)
{
return function ($v) use ($value, $function) {
$f = function ($call) use ($value, $function) {
return (is_callable($call) && is_callable($function)) ? $call($function($call), $value) : $value;
};
return is_callable($v) ? $f($v) : calc($v, $f);
};
}

How to merge return values of multiple functions?

How could I merge the return value of multiple functions?
I'm placing my option arrays within functions so I can call those functions (arrays) more easily because they will be needed more than once in different locations.
I would like to run my different arrays options each in their own function.
The reason for this is so I can allow devs to choose which of the arrays of those functions they want to use when extending but at the same time keep the function simple, rather than putting all my array values in one lengthy function.
So I just wondered is there a way like array_merge for functions where I could merge the returned values of multiple functions?
Here is an example of what I am doing...
function One() {
$var = array(1,2);
return $var;
}
function Two() {
$var = array(3,4);
return $var;
}
// Like array merge I would like to merge the returned values of the functions
// Like $var = function_merge('One', 'Two');
So the value you would be just like array_merge();
Example: $var = array(1,2,3,4);
Call the functions that return an array in the array_merge() method itself. Like this:
$var = array_merge(One(), Two());
or, to address the concern #manian brought up, use this:
$var = array_merge(array_values(One()), array_values(Two()));
// array_values() removes and resets an array's indexes
This will return
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
Hmm... maybe there are some other ideas?
I was overthinking this I think. Just thought of storing each function in a $var then merging those $vars
Like...
$var_1 = One();
$var_2 = Two();
$output = array_merge($var_1, $var_2);
print_r($output);
// Returns
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
for static usage
function function_merge($fnc1, $fnc2) {
return array_merge($fnc1(), $fnc2());
}
//use => function_merge('one', 'two');
for dynamic usage
function function_merge() {
$arguments = func_get_args();
$result = [];
if (is_array($arguments) && (count($arguments) > 0)) {
foreach ($arguments as $fnc) {
if (function_exists($fnc)) {
$result = array_merge($result, $fnc());
}
}
}
return $result;
}
//use => function_merge('one', 'two', 'three', 'four');
//use => function_merge('vegas', 'newyork', 'ohio');
Here is the method that you asked for,
$merged = array();
function One($merged) {
$var = array(1,2);
return array_merge($merged, $var);
}
function Two($merged) {
$var = array(3,4);
return array_merge($merged, $var);
}
$merged = One($merged);
$merged = Two($merged);
print_r($merged);

Get the last dimension of each element of an array

I have an array that might be any depth or number of elements:
$ra['a'] = 'one';
$ra['b']['two'] = 'b2';
$ra['c']['two']['three'] = 'c23';
$ra['c']['two']['four'] = 'c24';
$ra['c']['five']['a'] = 'c5a';
I want to have an array of the strings, like this:
array (
0 => 'one',
1 => 'b2',
2 => 'c23',
3 => 'c24',
4 => 'c5a',
)
Here is a recursive function I made. It seems to work. But I'm not sure that I'm doing it right, as far as declaring the static, and when to unset the static var (in case I want to use the function again, I dont want that old static array)
function lastthinggetter($ra){
static $out;
foreach($ra as $r){
if(is_array($r))
lastthinggetter($r);
else
$out[] = $r;
}
return $out;
}
How do I make sure each time I call the function, the $out var is fresh, every time? Is there a better way of doing this?
Maybe check if we're in recursion?
function lastthinggetter($ra, $recurse=false){
static $out;
foreach($ra as $r){
if(is_array($r))
lastthinggetter($r, true);
else
$out[] = $r;
}
$tmp = $out;
if(!$recurse)
unset($out);
return $tmp;
}
Your last version will probably work correctly. However, if you want to get rid of the static variable you could also do it like this:
function getleaves($ra) {
$out=array();
foreach($ra as $r) {
if(is_array($r)) {
$out=array_merge($out,getleaves($r));
}
else {
$out[] = $r;
}
}
return $out;
}
The key here is, that you actually return the so far found values at the end of your function but so far you have not 'picked them up' in the calling part of your script. This version works without any static variables.
I'll simply use array_walk_recursive over here instead like as
array_walk_recursive($ra, function($v)use(&$result) {
$result[] = $v;
});
Demo

Call a function within a function display both within array

how do I call a function from within a function?
function tt($data,$s,$t){
$data=$data;
echo '[[';
print_r($data);
echo ']]';
if($t==0){
$data[]=$s;
tt($data,'two',1);
}else{
$data[]=$s;
}
return $data;
}
print_r(tt('','one',0));
I want 'two' to be shown within the array like
$o[]='one';
$o[]='two';
print_r($o);
function tt($s, $t, array $data = array()) {
$data[] = $s;
if ($t == 0) {
$data = tt('two', 1, $data);
}
return $data;
}
print_r(tt('one', 0));
This is all that's really needed.
Put the array as the last argument and make it optional, because you don't need it on the initial call.
When calling tt recursively, you need to "catch" its return data, otherwise the recursive call simply does nothing of lasting value.
No need for the else, since you're going to append the entry to the array no matter what and don't need to write that twice.
Try this one (notice the function signature, the array is passed by ref &$data):
function tt(&$data,$s,$t){
echo '[[';
print_r($data);
echo ']]';
if($t==0){
$data[]=$s;
tt($data,'two',1);
}else{
$data[]=$s;
}
return $data;
}
$array = [];
tt($array,'one',0);
print_r($array);
/**
Array
(
[0] => one
[1] => two
)
*/
try this
function tt($data,$s,$t){
global $data;
if($t==0){
$data[]=$s;
tt($data,'two',1);
}else{
$data[]=$s;
}
return $data;
}
print_r(tt('','one',0));
OUTPUT :
Array
(
[0] => one
[1] => two
)
DEMO

Recursive function with unknown depth of values. Return all values (undefined depth)

I have a question about a recursive PHP function.
I have an array of ID’s and a function, returning an array of „child id’s“ for the given id.
public function getChildId($id) {
…
//do some stuff in db
…
return childids;
}
One childid can have childids, too!
Now, I want to have an recursive function, collecting all the childids.
I have an array with ids like this:
$myIds = array("1111“,"2222“,"3333“,“4444“,…);
and a funktion:
function getAll($myIds) {
}
What I want: I want an array, containing all the id’s (including an unknown level of childids) on the same level of my array. As long as the getChildId($id)-function is returning ID’s…
I started with my function like this:
function getAll($myIds) {
$allIds = $myIds;
foreach($myIds as $mId) {
$childids = getChildId($mId);
foreach($childids as $sId) {
array_push($allIds, $sId);
//here is my problem.
//what do I have to do, to make this function rekursive to
//search for all the childids?
}
}
return $allIds;
}
I tried a lot of things, but nothing worked. Can you help me?
Assuming a flat array as in your example, you simply need to call a function that checks each array element to determine if its an array. If it is, the function calls it itself, if not the array element is appended to a result array. Here's an example:
$foo = array(1,2,3,
array(4,5,
array(6,7,
array(8,9,10)
)
),
11,12
);
$bar = array();
recurse($foo,$bar);
function recurse($a,&$bar){
foreach($a as $e){
if(is_array($e)){
recurse($e,$bar);
}else{
$bar[] = $e;
}
}
}
var_dump($bar);
DEMO
I think this code should do the trick
function getAll($myIds) {
$allIds = Array();
foreach($myIds as $mId) {
array_push($allIds, $mId);
$subids = getSubId($mId);
foreach($subids as $sId) {
$nestedIds = getAll($sId);
$allIds = array_merge($allIds, $nestedIds);
}
}
return $allIds;
}

Categories