Recursive PHP Function - php

I am trying to solve this problem to learn logic formulations, but this one's really taken too much of my time already.
Rules are simple, No loops and no built in PHP functions (eg. print_r, is_array.. etc).
This is what I have come up with so far.
function displayArray(array $inputArray, $ctr = 0, $tempArray = array()) {
//check if array is equal to temparray
if($inputArray != $tempArray) {
// check if key is not empty and checks if they are not equal
if($inputArray[$ctr]) {
// set current $tempArray key equal to $inputArray's corresponding key
$tempArray[$ctr] = $inputArray[$ctr];
if($tempArray[$ctr] == $inputArray[$ctr]) {
echo $tempArray[$ctr];]
}
$ctr++;
displayArray($inputArray, $ctr);
}
}
}
This program outputs this:
blackgreen
The problem starts when it reaches the element that is an array
$array = array(
'black',
'green',
array(
'purple',
'orange'
)
);
displayArray($array);
Any tips?
This what the return value is supposed to be: blackgreenpurpleorange

This was fun. I decided to make it work with most data types while I was at it. Just don't throw it any objects or nulls and things should work.
No more # error suppression. Now returns the string instead of echoing it.
I realized too late that isset() is actually a language construct rather than a function, and went with a null termination strategy to determine the end of the arrays.
function concatinateRecursive($array, $i = 0) {
static $s = '';
static $depth = 0;
if ($i == 0) $depth++;
// We reached the end of this array.
if ($array === NULL) {
$depth--;
return true;
}
if ($array === array()) return false; // empty array
if ($array === '') return false; // empty string
if (
$array === (int)$array || // int
$array === (float)$array || // float
$array === true || // true
$array === false || // false
$array === "0" || // "0"
$array == "1" || // "1" "1.0" etc.
(float)$array > 1 || // > "1.0"
(int)$array !== 1 // string
)
{
$s .= "$array";
return false;
}
// Else we've got an array. Or at least something we can treat like one. I hope.
$array[] = NULL; // null terminate the array.
if (!concatinateRecursive($array[$i], 0, $s)) {
$depth--;
return concatinateRecursive($array, ++$i, $s);
}
if ($depth == 1) {
return $s;
}
}
$array = array(
'black',
'green',
array(
'purple',
'orange'
)
);
echo concatinateRecursive($array);
blackgreenpurpleorange
Live demo

What about this? You must check if it is array or not.
function display_array(&$array, $index=0) {
if (count($array)<=$index) return;
if (is_array($array[$index])) {
echo '[ ';
display_array($array[$index]);
echo '] ';
}
else
echo "'" . $array[$index] . "' ";
display_array($array, $index+1);
}
// Try:
// $a = ['black', 'green', ['purple', 'orange'], 'beer', ['purple', ['purple', 'orange']]];
// display_array($a);
// Output:
// 'black' 'green' [ 'purple' 'orange' ] 'beer' [ 'purple' [ 'purple' 'orange' ] ]

try this have to use some inbuilt function like isset and is_array but its a complete working recursive method without using loop.
function displayArray(array $inputArray, $ctr = 0) {
if(isset($inputArray[$ctr]))
{
if(is_array($inputArray[$ctr]))
{
return displayArray($inputArray[$ctr]);
}
else
{
echo $inputArray[$ctr];
}
}
else
{
return;
}
$ctr++;
displayArray($inputArray, $ctr);
}
$array = array(
'black',
'green',
array(
'purple',
'orange'
)
);
displayArray($array);
OUTPUT :
blackgreenpurpleorange
DEMO

complete answer
$myarray = array(
'black',
'green',
array(
'purple',
'orange'
)
);
function printAll($a) {
if (!is_array($a)) {
echo $a, ' ';
return;
}
foreach($a as $k => $value) {
if($k<10){
//printAll($k);
printAll($value);
}
}
}
printAll($myarray);

Related

search a php array for partial string match [duplicate]

This question already has answers here:
Filter multidimensional array based on partial match of search value
(3 answers)
Native function to filter array by prefix
(6 answers)
Closed 1 year ago.
I have an array and I'd like to search for the string 'green'. So in this case it should return the $arr[2]
$arr = array(0 => 'blue', 1 => 'red', 2 => 'green string', 3 => 'red');
is there any predefined function like in_array() that does the job rather than looping through it and compare each values?
For a partial match you can iterate the array and use a string search function like strpos().
function array_search_partial($arr, $keyword) {
foreach($arr as $index => $string) {
if (strpos($string, $keyword) !== FALSE)
return $index;
}
}
For an exact match, use in_array()
in_array('green', $arr)
You can use preg_grep function of php. It's supported in PHP >= 4.0.5.
$array = array(0 => 'blue', 1 => 'red', 2 => 'green string', 3 => 'red');
$m_array = preg_grep('/^green\s.*/', $array);
$m_array contains matched elements of array.
There are several ways...
$arr = array(0 => 'blue', 1 => 'red', 2 => 'green string', 3 => 'red');
Search the array with a loop:
$results = array();
foreach ($arr as $value) {
if (strpos($value, 'green') !== false) { $results[] = $value; }
}
if( empty($results) ) { echo 'No matches found.'; }
else { echo "'green' was found in: " . implode('; ', $results); }
Use array_filter():
$results = array_filter($arr, function($value) {
return strpos($value, 'green') !== false;
});
In order to use Closures with other arguments there is the use-keyword. So you can abstract it and wrap it into a function:
function find_string_in_array ($arr, $string) {
return array_filter($arr, function($value) use ($string) {
return strpos($value, $string) !== false;
});
}
$results = find_string_in_array ($arr, 'green');
if( empty($results) ) { echo 'No matches found.'; }
else { echo "'green' was found in: " . implode('; ', $results); }
Here's a working example: http://codepad.viper-7.com/xZtnN7
PHP 5.3+
array_walk($arr, function($item, $key) {
if(strpos($item, 'green') !== false) {
echo 'Found in: ' . $item . ', with key: ' . $key;
}
});
for search with like as sql with '%needle%' you can try with
$input = preg_quote('gree', '~'); // don't forget to quote input string!
$data = array(
1 => 'orange',
2 => 'green string',
3 => 'green',
4 => 'red',
5 => 'black'
);
$result = preg_filter('~' . $input . '~', null, $data);
and result is
{
"2": " string",
"3": ""
}
function check($string)
{
foreach($arr as $a) {
if(strpos($a,$string) !== false) {
return true;
}
}
return false;
}
A quick search for a phrase in the entire array might be something like this:
if (preg_match("/search/is", var_export($arr, true))) {
// match
}
function findStr($arr, $str)
{
foreach ($arr as &$s)
{
if(strpos($s, $str) !== false)
return $s;
}
return "";
}
You can change the return value to the corresponding index number with a little modification if you want, but since you said "...return the $arr[2]" I wrote it to return the value instead.
In order to find out if UTF-8 case-insensitive substring is present in array, I found that this method would be much faster than using mb_strtolower or mb_convert_case:
Implode the array into a string: $imploded=implode(" ", $myarray);.
Convert imploded string to lowercase using custom function:
$lowercased_imploded = to_lower_case($imploded);
function to_lower_case($str)
{
$from_array=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","Ä","Ö","Ü","Õ","Ž","Š"];
$to_array=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","ä","ö","ü","õ","ž","š"];
foreach($from_array as $key=>$val){$str=str_replace($val, $to_array[$key], $str);}
return $str;
}
Search for match using ordinary strpos: if(strpos($lowercased_imploded, "substring_to_find")!==false){do something}
This is a function for normal or multidimensional arrays.
Case in-sensitive
Works for normal arrays and multidimentional
Works when finding full or partial stings
Here's the code (version 1):
function array_find($needle, array $haystack, $column = null) {
if(is_array($haystack[0]) === true) { // check for multidimentional array
foreach (array_column($haystack, $column) as $key => $value) {
if (strpos(strtolower($value), strtolower($needle)) !== false) {
return $key;
}
}
} else {
foreach ($haystack as $key => $value) { // for normal array
if (strpos(strtolower($value), strtolower($needle)) !== false) {
return $key;
}
}
}
return false;
}
Here is an example:
$multiArray = array(
0 => array(
'name' => 'kevin',
'hobbies' => 'Football / Cricket'),
1 => array(
'name' => 'tom',
'hobbies' => 'tennis'),
2 => array(
'name' => 'alex',
'hobbies' => 'Golf, Softball')
);
$singleArray = array(
0 => 'Tennis',
1 => 'Cricket',
);
echo "key is - ". array_find('cricket', $singleArray); // returns - key is - 1
echo "key is - ". array_find('cricket', $multiArray, 'hobbies'); // returns - key is - 0
For multidimensional arrays only - $column relates to the name of the key inside each array.
If the $needle appeared more than once, I suggest adding onto this to add each key to an array.
Here is an example if you are expecting multiple matches (version 2):
function array_find($needle, array $haystack, $column = null) {
$keyArray = array();
if(is_array($haystack[0]) === true) { // for multidimentional array
foreach (array_column($haystack, $column) as $key => $value) {
if (strpos(strtolower($value), strtolower($needle)) !== false) {
$keyArray[] = $key;
}
}
} else {
foreach ($haystack as $key => $value) { // for normal array
if (strpos(strtolower($value), strtolower($needle)) !== false) {
$keyArray[] = $key;
}
}
}
if(empty($keyArray)) {
return false;
}
if(count($keyArray) == 1) {
return $keyArray[0];
} else {
return $keyArray;
}
}
This returns the key if it has just one match, but if there are multiple matches for the $needle inside any of the $column's then it will return an array of the matching keys.
Hope this helps :)

How to check an empty slot in 3 dimensional array in PHP?

I have coding about 3 dimensional array. I need a function to automatically check where the empty slot is, and then insert the empty array ($rhw[104][1][2]) values Class C.
The coding structure is,
$rhw[101][1][2] = "Class A";
$rhw[102][1][2] = "Class B";
$rhw[103][1][2] = "";
And i just can make like the coding below,
if (empty($rhw[103][1][2])) {
echo "TRUE";
} else {
echo "FALSE";
}
But there is already declared like --- if (empty($rhw[103][1][2])) ---
I dont know how to automatically check where the empty slot is (which is $rhw[103][1][2]).
Such as,
if (empty($rhw[][][])) {
insert "Class C";
} else {
echo "The slot has been fulfilled";
}
But it can not be proceed.
Thank you, guys! :)
Taken from in_array() and multidimensional array
in_array() does not work on multidimensional arrays. You could write a recursive function to do that for you:
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
Usage:
$b = array(array("Mac", "NT"), array("Irix", "Linux"));
echo in_array_r("Irix", $b) ? 'found' : 'not found';
For check a particular position, you can use a more simple solution:
if(isset($rhw[103]) && isset($rhw[103][1]) && isset($rhw[103][1][2]))
{
echo "TRUE";
}
else
{
echo "FALSE";
}
Or use a function for check isset for each multidimensional position.
function check_multidimensional($data, $a, $b, $c)
{
return isset($data[a]) && isset($data[$a][$b]) && isset($data[$a][$b][$c]);
}
You can even make a more generic function for N dimensions.
Coba ini deh udah di edit. penasaran :p
$rwh = array(
101 => array( 1 => array(1 => 'Value key 1', 2 => 'Class A')),
102 => array( 1 => array(1 => 'Value key 1', 2 => 'Class B')),
103 => array( 1 => array(1 => 'Value key 1', 2 => ''))
);
echo 'PERTAMA : '.print_r($rwh);
function emptyArray($array = array() , $newval = '')
{
$key_val = array();
if(is_array($array) && !empty($array))
{
foreach($array as $key => $value)
{
$key_val[$key] = emptyArray($value, $newval);
}
}
else if(empty($array))
return $newval;
else
return $array;
return $key_val;
}
$hasil = emptyArray($rwh, 'Class C');
echo "AKHIR : ". print_r($hasil);

unset inside eval not working

I'm trying to remove an item from an array based on string;
public function delete($path){
// a key path given
if(strpos($path, '.') !== false){
$parts = explode('.', $path);
$first_key = array_shift($parts);
$data = $this->get($path);
// first key doesn't exist
if($data === false)
return false;
$parts = implode('"]["', $parts);
if(eval('if(isset($data["'.$parts.'"])){ unset($data["'.$parts.'"]); return true; } return false;'))
return $this->set($first_key, $data);
}
// a single key given
if(isset($this->data[$path]){
unset($this->data[$path]);
return true;
}
return false;
}
And it only works for single keys. Apparently the eval doesn't modify $data for some reason.
delete('test') works, but delete('test.child') doesn't...
I don't see why you'd need eval() here. See the following to replace your eval() construct:
<?php
function removeFromArray(&$array, $path)
{
if (!is_array($path)) {
$path = explode('.', trim($path, '.'));
}
$current = &$array;
while ($path) {
$key = array_shift($path);
// isset() would fail on `$array[$key] === null`
if (!array_key_exists($key, $current)) {
// abort if the array element does not exist
return false;
}
if (!$path) {
// reached the last element
unset($current[$key]);
return true;
}
if (!is_array($current[$key])) {
// can't go deeper, so abort
return false;
}
// continue with next deeper element
$current = &$current[$key];
}
return false;
}
$data = array(
'a' => 1,
'b' => array(
'c' => 2,
'd' => 3,
'e' => array(
'f' => 4,
),
),
);
var_dump(
removeFromArray($data, 'b.e.f'),
$data,
removeFromArray($data, 'b.c'),
$data
);
function unset_multiple($arr = [], $keys = [], $limitKeys = 30){
if($keys && count($keys) <= $limitKeys && is_array($arr) && count($arr) > 0){
foreach($keys as $key){
$keys[$key] = null;
}
return array_diff_key($arr, $keys);
} else{
throw new Exception("Input array is invalid format or number of keys to remove too large");
}
}
Example called:
$arr = array("name" => "Vuong", "age" => 20, "address" => "Saigon");
$res = unset_multiple($arr, ["name", "age"]);
//Result: ["address" => "Saigon"]
Make sure $keys param has all available keys in $arr param (only two-dimensional arrays). Need to remember this function is a helper to quickly removing multiple elements of array, not a function returns the absolute accurate results for all cases.

string min,max length function

I'm trying to check min and max length of strings:
If I pass it an array, such as follows, I want the values to be returned if true and NULL if false:
$lenghts = array('a' => array('min' => 20, 'max' => 70),
'b' => array('min' => 50, 'max' => 800),
'c' => array('min' => 3, 'max' =>8));
And the values are:
$values = array('thread_title' => 'this is it', 'thread_content' => 'this is not it', 'thread_tags' => 'also not it')
;
EDIT
It's like 5am here (really quite sleepy), I should copied and pasted the correct version, sorry:
function string_min_max($string_array, $array)
{
$returns = array(); # store returned values
foreach ($array as $key)
{
# check for minimum:
if (array_key_exists('min', $key))
{
$minimum = (strlen($string_array[$key]) < $key['min'] ? $key = NULL : $key);
}
if (array_key_exists('max', $key))
{
$maximum = (strlen($string_array($key)) > $key['max'] ? $key = NULL : $key);
}
if ($minimum !== NULL && $maximum !== NULL)
{
$returns[$key]['min'] = $minimum;
$returns[$key]['max'] = $maximum;
}
}
}
This does not work:
string_min_max($values, $lengths);
This code is reducable to:
function string_min_max($array)
{
$returns = array(); # store returned values
foreach ($array as $key)
{
# check for minimum:
if (TRUE)
{
$minimum = (FALSE ? $key = NULL : $key);
}
}
}
OR:
function string_min_max($array)
{
$returns = array(); # store returned values
foreach ($array as $key)
{
$minimum = $key;
}
}
OR:
function string_min_max($array)
{
$returns = array(); # store returned values
}
OR:
(void)
So the answer is: no. It won't work.
Without looking too much at the details, one obvious problem is that you are not returning anyting from your function; you are building an array but you don´t use it so it gets destroyed at the moment your function ends.
I think that at least you will need this at the end of your function:
return $returns;
} // end function
You can then call your function like:
$results = string_min_max($values, $lenghts);
if use this for validate string by length and chars :
function checkString($string, $regex, $minlenght = 3, $maxlenght = 20) {
if(preg_match($regex, $string) && strlen($string) >= $minlenght && strlen($string) <= $maxlenght) return true;
return false;
}

How to check if a certain part of the array exists in another array?

I have an two associative arrayes and I want to check if
$array1["foo"]["bar"]["baz"] exists in $array2["foo"]["bar"]["baz"]
The values doesn't matter, just the "path".
Does array_ intersect_ assoc do what I need?
If not how can I write one myself?
Try this:
<?php
function array_path_exists(&$array, $path, $separator = '/')
{
$a =& $array;
$paths = explode($separator, $path);
$i = 0;
foreach ($paths as $p) {
if (isset($a[$p])) {
if ($i == count($paths) - 1) {
return TRUE;
}
elseif(is_array($a[$p])) {
$a =& $a[$p];
}
else {
return FALSE;
}
}
else {
return FALSE;
}
$i++;
}
}
// Test
$test = array(
'foo' => array(
'bar' => array(
'baz' => 1
)
),
'bar' => 1
);
echo array_path_exists($test, 'foo/bar/baz');
?>
If you only need to check if the keys exist you could use a simple if statement.
<?php
if (isset($array1["foo"]["bar"]["baz"]) && isset($array2["foo"]["bar"]["baz"]
)) {
//exists
}

Categories