change empty array element to a value - php

i have an array like this
Array ([0]=>'some values'[1]=>'')
I want to change the empty elemnt of an array to a value of 5
how can I do that
thanks

5.3 version
$arr = array_map(function($n) { return !empty($n) ? $n : 5; }, $arr);

If you know at which position it is, just do:
$array[1] = 5;
If not, loop through it and check with === for value and type equality:
foreach($array as &$element) { //get element as a reference so we can change it
if($element === '') { // check for value AND type
$element = 5;
}
}

You can use array_map for this:
function emptyToFive($value) {
return empty($value) ? 5 : $value;
}
$arr = array_map(emptyToFive, $arr);
As of PHP 5.3, you can do:
$func = function($value) {
return empty($value) ? 5 : $value;
};
$arr = array_map($func, $arr);
EDIT: If empty does not fit your requirements, you should perhaps change the condition to $value === '' as per #Felix's suggestion.

This $array[1] = 5;

Related

PHP array with url values to new array with combined values

I have tried for a long time but couldn't find a way to merge an array in to a new one.
Mostly I get lost in looping and matching.;(
I would like to recieve a php 5 method that can do the following:
Example 1
Lets say there is an array with url's like:
Array(
'a',
'a/b/c',
'a/b/c/d/e',
'a/y',
'b/z',
'b/z/q/',
)
Every last folder of the url's is the folder where a user has the right to view.
I would like to send the array to a method that returns a new array like:
Array[](
'a/c/e'
'a/y'
'z/q'
)
The method has combined some elements of the origninal array into one element.
This because there is a match in allowed ending folders.
Example 2
Array(
'projects/projectA/books'
'projects/projectA/books/cooking/book1'
'projects/projectA/walls/wall'
'projects/projectX/walls/wall'
'projects/projectZ/'
'projects/projectZ/Wood/Cheese/Bacon'
)
I would like to get a an array like:
Array[](
'books/book1'
'wall'
'wall'
'projectZ/Bacon'
)
Then it would be great (specialy in case of the 'wall' values) to have some references to the full path's of the original array.
Do it like below:-
<?php
$array = Array(
'projects/projectA/books',
'projects/projectA/books/cooking/book1',
'projects/projectA/walls/wall',
'projects/projectX/walls/wall',
'projects/projectZ/',
'projects/projectZ/Wood/Cheese/Bacon'
);// original array
$final_array =array(); // new array variable
foreach($array as $key=>$arr){ // iterate over original array
$exploded_string = end(array_filter(explode('/',$arr))); // get last-value from the url string
foreach($array as $ar){ // iterate again the original array to compare this string withh each array element
$new_exploded_string = end(array_filter(explode('/',$ar))); // get the new-last-values from url string again
if($arr !== $ar && strpos($ar,$exploded_string) !==false){ // if both old and new url strings are not equal and old-last-value find into url string
if($exploded_string == $new_exploded_string ){ // if both new-last-value and old-last-value are equal
$final_array[] = $exploded_string;
}else{
$final_array[] = $exploded_string.'/'.$new_exploded_string ;
}
}
}
}
print_r($final_array);
Output:-https://eval.in/846738
Well, there isn't a single built-in function for this ;)
$items = array(
'projects/projectA/books',
'projects/projectA/books/cooking/book1',
'projects/projectA/walls/wall',
'projects/projectX/walls/wall',
'projects/projectZ/',
'projects/projectZ/Wood/Cheese/Bacon',
'hold/mold/gold/sold/fold',
'hold/mold/gold',
'raja/maza/saza',
'raja/maza',
'mohit/yenky/client/project',
);
echo '$items = ' . nl2br(htmlspecialchars(print_r($items, true))); //Debug
// Sort, so the shorter basePath comes before the longer subPath
usort($items, function($a, $b) {
if (strlen($a) == strlen($b)) {
return 0;
} else {
return strlen($a) > strlen($b) ? 1 : -1;
}
});
$result = array();
while($basePath = array_shift($items)) { // As long as there is a next item
$basePath = rtrim($basePath, '/'); // Right trim extra /
foreach($items as $idx => $subPath) {
if (strpos($subPath, $basePath . '/') === 0) {
// $subPath begins with $basePath
$result[] = preg_replace('#.*/#', '', $basePath) . '/' . preg_replace('#.*/#', '', rtrim($subPath, '/'));
unset($items[$idx]); // Remove item from array, so it won't be matched again
continue 2; // Continue with next while($basePath = array_shift($items))
}
}
// No subPath found, otherwise continue would have called (skipping below code)
$result[] = preg_replace('#.*/#', '', $basePath);
}
echo '$result = ' . nl2br(htmlspecialchars(print_r($result, true))); //Debug
PHPFiddle: http://phpfiddle.org/main/code/ugq9-hy0i
You can avoid using nested loops (and, actually, you should avoid):
sort($array);
$carry = array_shift($array);
$result = [];
$i = 0;
$lastItem = array_reduce($array, function ($carry, $item) use (&$result, &$i) {
$result[$i] = isset($result[$i])
? array_merge($result[$i], [basename($carry)])
: [basename($carry)];
if (strpos($item, $carry) !== 0) {
$i += 1;
}
return $item;
}, $carry);
if (!empty($lastItem)) {
$result[$i] = isset($result[$i])
? array_merge($result[$i], [basename($lastItem)])
: [basename($lastItem)];
}
$result = array_map(function ($item) {
return implode('/', $item);
}, $result);
Here is working demo.
We use array_reduce here to get access to the previously processed item. Also, PHP has function basename, that retrieves the basename. So you can use it and do not reinvent the wheel.

Which member of array does the string contain in PHP?

How can I check if a string contains a member of an array, and return the index (integer) of the relevant member?
Let's say my string is this :
$string1 = "stackoverflow.com";
$string2 = "superuser.com";
$r = array("queue" , "stack" , "heap");
get_index($string1 , $r); // returns 1
get_index($string2 , $r); // returns -1 since string2 does not contain any element of array
How can I write this function in an elegant (short) and efficient way ?
I found a function (expression ? ) that checks if the string contains a member of an array :
(0 < count(array_intersect(array_map('strtolower', explode(' ', $string)), $array)))
but this is a boolean. does the count() function return what I want in this statement ?
Thanks for any help !
function get_index($str, $arr){
foreach($arr as $key => $val){
if(strpos($str, $val) !== false)
return $key;
}
return -1;
}
Demo: https://eval.in/95398
This will find the number of matching elements in your array, if you want all matching keys, use the commented lines instead:
function findMatchingItems($needle, $haystack){
$foundItems = 0; // start counter
// $foundItems = array(); // start array to save ALL keys
foreach($haystack as $key=>$value){ // start to loop through all items
if( strpos($value, $needle)!==false){
++$foundItems; // if found, increase counter
// $foundItems[] = $key; // Add the key to the array
}
}
return $foundItems; // return found items
}
findMatchingItems($string1 , $r);
findMatchingItems($string2 , $r);
If you want to return all matching keys, just change $foundItems to an array and add the keys in the if-statement (switch to the commented lines).
If you only want to know if something matches or not
function findMatchingItems($needle, $haystack){
if( strpos($value, $needle)!==false){
return true;
break; // <- This is important. This stops the loop, saving time ;)
}
return false;// failsave, if no true is returned, this will return
}
I would do a function like this:
function getIndex($string, $array) {
$index = -1;
$i = 0;
foreach($array as $array_elem) {
if(str_pos($array_elem, $string) !== false) {
$index = $i;
}
$i++;
}
return $index;
}

extract values found in array from string

I am stuck. What I would like to do: In the $description string I would like to check if any of the values in the different arrays can be found. If any of the values match, I need to know which one per array. I am thinking that I need to do a function for each $a, $b and $c, but how, I don't know
if($rowGetDesc = mysqli_query($db_mysqli, "SELECT descFilter FROM tbl_all_prod WHERE lid = 'C2'")){
if (mysqli_num_rows($rowGetDesc) > 0){
while($esk= mysqli_fetch_array($rowGetDesc)){
$description = sanitizingData($esk['descFilter']);
$a = array('1:100','1:250','1:10','2');
$a = getExtractedValue($a,$description);
$b = array('one','five','12');
$b = getExtractedValue($b,$description);
$c = array('6000','8000','500');
$c = getExtractedValue($c,$description);
}
}
}
function getExtractedValue($a,$description){
?
}
I would be very very greatful if anyone could help me with this.
many thanks Linda
It would be better to create each array just once and not in every iteration of the while loop.
Also using the same variable names in the loop is not recommended.
if($rowGetDesc = mysqli_query($db_mysqli, "SELECT descFilter FROM tbl_all_prod WHERE lid = 'C2'")){
if (mysqli_num_rows($rowGetDesc) > 0){
$a = array('1:100','1:250','1:10','2');
$b = array('one','five','12');
$c = array('6000','8000','500');
while($esk= mysqli_fetch_array($rowGetDesc)){
$description = sanitizingData($esk['descFilter']);
$aMatch = getExtractedValue($a,$description);
$bMatch = getExtractedValue($b,$description);
$cMatch = getExtractedValue($c,$description);
}
}
}
Use strpos to find if the string exists (or stripos for case insensitive searches). See http://php.net/strpos. If the string exists it will return the matching value in the array:
function getExtractedValue($a,$description) {
foreach($a as $value) {
if (strpos($description, $value) !== false) {
return $value;
}
}
return false;
}
there s a php function for that which return a boolean.
or if you wanna check if one of the element in arrays is present in description, maybe you 'll need to iterate on them
foreach($array as element){
if(preg_match("#".$element."#", $description){
echo "found";
}
}
If your question is correctly phrased and indeed you are searching a string, you should try something like this:
function getExtractedValue($a, $description) {
$results = array();
foreach($a as $array_item) {
if (strpos($array_item, $description) !== FALSE) {
$results[] = $array_item;
}
}
return $results;
}
The function will return an array of the matched phrases from the string.
Try This..
if ( in_array ( $str , $array ) ) {
echo 'It exists'; } else {
echo 'Does not exist'; }

PHP: find biggest overlap between multiple strings

I have this array:
$array = array('abc123', 'ac123', 'tbc123', '1ac123');
I want to compare each string to each other and find the longest common substring. In the example above the result would be c123.
Update
I've completely misunderstood the question; the aim was to find the biggest overlap between an array of strings:
$array = array('abc123', 'ac123', 'tbc123', '1ac123');
function overlap($a, $b)
{
if (!strlen($b)) {
return '';
}
if (strpos($a, $b) !== false) {
return $b;
}
$left = overlap($a, substr($b, 1));
$right = overlap($a, substr($b, 0, -1));
return strlen($left) > strlen($right) ? $left : $right;
}
$biggest = null;
foreach ($array as $item) {
if ($biggest === null) {
$biggest = $item;
}
if (($biggest = overlap($biggest, $item)) === '') {
break;
}
}
echo "Biggest match = $biggest\n";
I'm not great at recursion, but I believe this should work ;-)
Old answer
I would probably use preg_grep() for that; it returns an array with the matches it found based on your search string:
$matches = preg_grep('/' . preg_quote($find, '/') . '/', $array);
Alternatively, you could use array_filter():
$matches = array_filter($array, function($item) use ($find) {
return strpos($item, $find) !== false;
});
I need to extract the value "c123" like it is the biggest match for all strings in array
I think what you would want to do here is then sort the above output based on string length (i.e. smallest string length first) and then take the first item:
if ($matches) {
usort($matches, function($a, $b) {
return strlen($a) - strlen($b);
});
echo current($matches); // take first one: ac123
}
Let me know if I'm wrong about that.
If you're just after knowing whether $find matches an element exactly:
$matching_keys = array_keys($array, $find, true); // could be empty array
Or:
$matching_key = array_search($find, $array, true); // could be false
Or event:
$have_value = in_array($find, $array, true);
in_array($find, $array);
returns true if it's in the array, but it has to be the exact match, in your case it won't finde 'ac123'.
if you want to see if it contains the string then you need to loop through the array and use a preg_match() or similar
You could use array_filter with a callback.
$output = array_filter ($input, function ($elem) { return false !== strpos ($elem, 'c123'); });
<?php
$array1 = array('abc123', 'ac123', 'tbc123', '1ac123');
if (in_array("c123", $array1)) {
echo "Got c123";
}
?>
You can use in_array as used here http://codepad.org/nOdaajNe
or use can use array_search as used here http://codepad.org/DAC1bVCi
see if it can help you ..
Documentation link : http://php.net/manual/en/function.array-search.php and http://www.php.net/manual/en/function.in-array.php

Checking if array is multidimensional or not?

What is the most efficient way to check if an array is a flat array
of primitive values or if it is a multidimensional array?
Is there any way to do this without actually looping through an
array and running is_array() on each of its elements?
Use count() twice; one time in default mode and one time in recursive mode. If the values match, the array is not multidimensional, as a multidimensional array would have a higher recursive count.
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
This option second value mode was added in PHP 4.2.0. From the PHP Docs:
If the optional mode parameter is set to COUNT_RECURSIVE (or 1), count() will recursively count the array. This is particularly useful for counting all the elements of a multidimensional array. count() does not detect infinite recursion.
However this method does not detect array(array()).
The short answer is no you can't do it without at least looping implicitly if the 'second dimension' could be anywhere. If it has to be in the first item, you'd just do
is_array($arr[0]);
But, the most efficient general way I could find is to use a foreach loop on the array, shortcircuiting whenever a hit is found (at least the implicit loop is better than the straight for()):
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
$c = array(1 => 'a',2 => 'b','foo' => array(1,array(2)));
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
function is_multi2($a) {
foreach ($a as $v) {
if (is_array($v)) return true;
}
return false;
}
function is_multi3($a) {
$c = count($a);
for ($i=0;$i<$c;$i++) {
if (is_array($a[$i])) return true;
}
return false;
}
$iters = 500000;
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi($a);
is_multi($b);
is_multi($c);
}
$end = microtime(true);
echo "is_multi took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi2($a);
is_multi2($b);
is_multi2($c);
}
$end = microtime(true);
echo "is_multi2 took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi3($a);
is_multi3($b);
is_multi3($c);
}
$end = microtime(true);
echo "is_multi3 took ".($end-$time)." seconds in $iters times\n";
?>
$ php multi.php
is_multi took 7.53565130424 seconds in 500000 times
is_multi2 took 4.56964588165 seconds in 500000 times
is_multi3 took 9.01706600189 seconds in 500000 times
Implicit looping, but we can't shortcircuit as soon as a match is found...
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
var_dump(is_multi($a));
var_dump(is_multi($b));
?>
$ php multi.php
bool(true)
bool(false)
For PHP 4.2.0 or newer:
function is_multi($array) {
return (count($array) != count($array, 1));
}
I think this is the most straight forward way and it's state-of-the-art:
function is_multidimensional(array $array) {
return count($array) !== count($array, COUNT_RECURSIVE);
}
After PHP 7 you could simply do:
public function is_multi(array $array):bool
{
return is_array($array[array_key_first($array)]);
}
You could look check is_array() on the first element, under the assumption that if the first element of an array is an array, then the rest of them are too.
I think you will find that this function is the simplest, most efficient, and fastest way.
function isMultiArray($a){
foreach($a as $v) if(is_array($v)) return TRUE;
return FALSE;
}
You can test it like this:
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
echo isMultiArray($a) ? 'is multi':'is not multi';
echo '<br />';
echo isMultiArray($b) ? 'is multi':'is not multi';
Don't use COUNT_RECURSIVE
click this site for know why
use rsort and then use isset
function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
Even this works
is_array(current($array));
If false its a single dimension array if true its a multi dimension array.
current will give you the first element of your array and check if the first element is an array or not by is_array function.
You can also do a simple check like this:
$array = array('yo'=>'dream', 'mydear'=> array('anotherYo'=>'dream'));
$array1 = array('yo'=>'dream', 'mydear'=> 'not_array');
function is_multi_dimensional($array){
$flag = 0;
while(list($k,$value)=each($array)){
if(is_array($value))
$flag = 1;
}
return $flag;
}
echo is_multi_dimensional($array); // returns 1
echo is_multi_dimensional($array1); // returns 0
I think this one is classy (props to another user I don't know his username):
static public function isMulti($array)
{
$result = array_unique(array_map("gettype",$array));
return count($result) == 1 && array_shift($result) == "array";
}
In my case. I stuck in vary strange condition.
1st case = array("data"=> "name");
2nd case = array("data"=> array("name"=>"username","fname"=>"fname"));
But if data has array instead of value then sizeof() or count() function not work for this condition. Then i create custom function to check.
If first index of array have value then it return "only value"
But if index have array instead of value then it return "has array"
I use this way
function is_multi($a) {
foreach ($a as $v) {
if (is_array($v))
{
return "has array";
break;
}
break;
}
return 'only value';
}
Special thanks to Vinko Vrsalovic
Its as simple as
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
This function will return int number of array dimensions (stolen from here).
function countdim($array)
{
if (is_array(reset($array)))
$return = countdim(reset($array)) + 1;
else
$return = 1;
return $return;
}
Try as follows
if (count($arrayList) != count($arrayList, COUNT_RECURSIVE))
{
echo 'arrayList is multidimensional';
}else{
echo 'arrayList is no multidimensional';
}
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);
Here is a nice one liner. It iterates over every key to check if the value at that key is an array. This will ensure true

Categories