Does not equal performing opposite in a foreach loop - php

I have an array that looks something like
array (size=7)
'car_make' => string 'BMW' (length=3)
'car_model' => string 'M3' (length=2)
'car_year' => string '2001' (length=4)
'car_price' => string '10000' (length=5)
'car_kilometers' => string '100000' (length=6)
'paint' => string 'black' (length=5)
'tires' => string 'pirelli' (length=7)
So basically there are a few base items in it that start with car_ and then a few extras.
I'm trying to search for each key that isn't car_* so paint and tires in this case. So I'm doing something like
foreach($_SESSION['car'][0] as $key=>$value)
{
if($key != preg_match('/car_.*/', $key))
{
echo 'Match';
}
}
Which I expected to echo out 2 Matches because of the 2 non car_ keys. Instead, this echos out 5 for the car_ keys.
But when I do
if($key == preg_match('/car_.*/', $key))
It echoes out 2 Matches for the 2 non car_ keys.
Where am I messing up or misunderstanding?

preg_match docs say about its return values:
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
So this wouldn't have worked in the first place.
I would use:
if ( substr($key, 0, 4) === "car_" )
...which is much less expensive as an operation than preg_match anyway.

According the documentation preg_match returns true when matching and false when not. So it appears that you are having some fun with PHP's type casting.
So rather than comparing the value you should check
if(true === preg_match('/car_.*/', $key))
This should take care of it.
Also, per the documentation:
Do not use preg_match() if you only want to check if one string is
contained in another string. Use strpos() or strstr() instead as they
will be faster.
Which would be:
if(false === str_pos('car_', $key))

From http://php.net/manual/en/function.preg-match.php
Return Values
preg_match() returns 1 if the pattern matches given subject, 0 if it
does not, or FALSE if an error occurred.
So you should compare it to 1 or to 0, not to a string.
The reason why your code was working but backwards is because comparing a number to a string produces interesting results:
From http://php.net/manual/en/types.comparisons.php
1 == "" is FALSE
0 == "" is TRUE

Related

PHP Group tabels [duplicate]

If 0 could be a possible key returned from array_search(), what would be the best method for testing if an element exists in an array using this function (or any php function; if there's a better one, please share)?
I was trying to do this:
if(array_search($needle, $haystack)) //...
But that would of course return false if $needle is the first element in the array. I guess what I'm asking is is there some trick I can do in this if statement to get it to behave like I want it? I tried doing these, but none of them worked:
$arr = array(3,4,5,6,7);
if(array_search(3, $arr) != false) //...
if(array_search(3, $arr) >= 0) //...
Appreciate the help.
This is the way:
if(array_search(3, $arr) !== false)
Note the use of the === PHP operator, called identical (not identical in this case). You can read more info in the official doc. You need to use it because with the use of the equal operator you can't distinguish 0 from false (or null or '' as well).
A better solution if you find the match and want to use the integer value is:
if (($pos = array_search(3, $arr)) !== false)
{
// do stuff using $pos
}
As an alternative to === and !==, you can also use in_array:
if (in_array($needle, $haystack))
As an alternative to ===, !==, and in_array(), you can use array_flip():
$arr = [3,4,5,6,7];
$rra = array_flip($arr);
if( $rra[3] !== null ):
var_dump('Do something, '.$rra[3].' exists!');
endif;
This is not fewer lines than the accepted answer. But it does allow you to get position and existence in a very human-readable way.
We want to find out if int 3 is in $arr, the original array:
array (size=5)
0 => int 3
1 => int 4
2 => int 5
3 => int 6
4 => int 7
array_flip creates a new array ($rra) with swapped key-value pairs:
array (size=5)
3 => int 0
4 => int 1
5 => int 2
6 => int 3
7 => int 4
Now we can verify the existence of int 3, which will (or will not be) a key in $rra with array_key_exists, isset, or by enclosing $rra[3]` in an if statement.
Since the value we are looking for could have an array key id of 0, we need to compare against null and not rely on evaluating 0 to false.
You can also make changes to the original array, should that be the use case, because if $rra[3] isn't null, $rra[3] will return what is the key (position 0, in this case) for the value in the original array.
if ( $rra[3] !== null ):
// evaluates to: unset( $array[0] );
unset( $arr[ $rra[3] ] );
endif;
This operation works just as well if you're working with an associative array.

how to find "http" in string from array?

In PHP I have an array like this:
array
0 => string 'open' (length=4)
1 => string 'http://www.google.com' (length=21)
2 => string 'blank' (length=5)
but it could also be like:
array
0 => string 'blank' (length=5)
1 => string 'open' (length=4)
2 => string 'http://www.google.com' (length=21)
now it is easy to find "blank" with in_array("blank", $array) but how can I see if one string is starting with "http"?
I've tried with
array_search('http', $array); // not working
array_search('http://www.google.com', $array); // is working
now everything after `http? could vary (how to write vary, varie? could be different is what I mean!)
Now do I need a regex or how can I check if http exists in array string?
Thanks for advices
"Welcome to PHP, there's a function for that."
Try preg_grep
preg_grep("/^http\b/i",$array);
Regex explained:
/^http\b/i
^\ / ^ `- Case insensitive match
| \/ `--- Boundary character
| `------ Literal match of http
`--------- Start of string
Try using the preg_grep function which returns an array of entries that match the pattern.
$array = array("open", "http://www.google.com", "blank");
$search = preg_grep('/http/', $array);
print_r($search);
Solution without regex:
$input = array('open', 'http://www.google.com', 'blank');
$output = array_filter($input, function($item){
return strpos($item, 'http') === 0;
});
Output:
array (size=1)
1 => string 'http://www.google.com' (length=21)
You can use preg_grep
$match = preg_grep("/http/",$array);
if(!empty($match)) echo "http exist in the array of string.";
or you can use foreach and preg_match
foreach($array as $check) {
if (preg_match("/http/", $check))
echo "http exist in the array of string.";
}

Eliminate Partial Strings from Array of Strings PHP

I can do this, I'm just wondering if there is a more elegant solution than the 47 hacked lines of code I came up with...
Essentially I have an array (the value is the occurrences of said string);
[Bob] => 2
[Theresa] => 3
[The farm house] => 2
[Bob at the farm house] => 1
I'd like to iterate through the array and eliminate any entries that are sub-strings of others so that the end result would be;
[Theresa] => 3
[Bob at the farm house] => 1
Initially I was looping like (calling this array $baseTags):
foreach($baseTags as $key=>$count){
foreach($baseTags as $k=>$c){
if(stripos($k,$key)){
unset($baseTags[$key]);
}
}
}
I'm assuming I'm looping through each key in the array and if there is the occurrence of that key inside another key to unset it... doesn't seem to be working for me though. Am I missing something obvious?
Thank you in advance.
-H
You're mis-using strpos/stripos. They can return a perfectly valid 0 if the string you're searching for happens to be at the START of the 'haystack' string, e.g. your Bob value. You need to explicitly test for this with
if (stripos($k, $key) !== FALSE) {
unset(...);
}
if strpos/stripos don't find the needle, they return a boolean false, which under PHP's normal weak comparison rules is equal/equivalent to 0. Using the strict comparison operators (===, !==), which compare type AND value, you'll get the proper results.
Don't forget as-well as needing !== false, you need $k != $key so your strings don't match themselves.
You have two problems inside your code-example:
You combine each key with each key, so not only others, but also itself. You would remove all entries so because "Bob" is a substring of "Bob", too.
stripos returns false if not found which can be confused with 0 that stands for found at position 0, which is also equal but not identical to false.
You need to add an additional check to not remove the same key and then fix the check for the "not found" case (Demo):
$baseTags = array(
'Bob' => 2,
'Theresa' => 3,
'The farm house' => 2,
'Bob at the farm house' => 1,
);
foreach ($baseTags as $key => $count)
{
foreach ($baseTags as $k => $c)
{
if ($k === $key)
{
continue;
}
if (false !== stripos($k, $key))
{
unset($baseTags[$key]);
}
}
}
print_r($baseTags);
Output:
Array
(
[Theresa] => 3
[Bob at the farm house] => 1
)

Checking if value exists in array with array_search()

If 0 could be a possible key returned from array_search(), what would be the best method for testing if an element exists in an array using this function (or any php function; if there's a better one, please share)?
I was trying to do this:
if(array_search($needle, $haystack)) //...
But that would of course return false if $needle is the first element in the array. I guess what I'm asking is is there some trick I can do in this if statement to get it to behave like I want it? I tried doing these, but none of them worked:
$arr = array(3,4,5,6,7);
if(array_search(3, $arr) != false) //...
if(array_search(3, $arr) >= 0) //...
Appreciate the help.
This is the way:
if(array_search(3, $arr) !== false)
Note the use of the === PHP operator, called identical (not identical in this case). You can read more info in the official doc. You need to use it because with the use of the equal operator you can't distinguish 0 from false (or null or '' as well).
A better solution if you find the match and want to use the integer value is:
if (($pos = array_search(3, $arr)) !== false)
{
// do stuff using $pos
}
As an alternative to === and !==, you can also use in_array:
if (in_array($needle, $haystack))
As an alternative to ===, !==, and in_array(), you can use array_flip():
$arr = [3,4,5,6,7];
$rra = array_flip($arr);
if( $rra[3] !== null ):
var_dump('Do something, '.$rra[3].' exists!');
endif;
This is not fewer lines than the accepted answer. But it does allow you to get position and existence in a very human-readable way.
We want to find out if int 3 is in $arr, the original array:
array (size=5)
0 => int 3
1 => int 4
2 => int 5
3 => int 6
4 => int 7
array_flip creates a new array ($rra) with swapped key-value pairs:
array (size=5)
3 => int 0
4 => int 1
5 => int 2
6 => int 3
7 => int 4
Now we can verify the existence of int 3, which will (or will not be) a key in $rra with array_key_exists, isset, or by enclosing $rra[3]` in an if statement.
Since the value we are looking for could have an array key id of 0, we need to compare against null and not rely on evaluating 0 to false.
You can also make changes to the original array, should that be the use case, because if $rra[3] isn't null, $rra[3] will return what is the key (position 0, in this case) for the value in the original array.
if ( $rra[3] !== null ):
// evaluates to: unset( $array[0] );
unset( $arr[ $rra[3] ] );
endif;
This operation works just as well if you're working with an associative array.

How to get this element from this array

I have an array $arr that when I var_dump looks like this. What's the easiest way to get the 2nd last item ('simple' in this case). I can't do $arr[4] because the number of items may vary per url, and I always want just the 2nd last. (note that there's an extra empty string at the end, which will always be there.)
array
0 => string 'http:' (length=5)
1 => string '' (length=0)
2 => string 'site.com'
3 => string 'group'
4 => string 'simple'
5 => string 'some-test-url'
6 => string '' (length=0)
So long as it is not a keyed or hashed array and it has more than two items...
$arr[count($arr) - 2];
Note: that my interpretation of second to last is second from the end. This may differ from yours. If so, subtract 3.
Get the count and subtract 3?
$arr[count($arr)-3]
if (!empty($arr) && count($arr)>1){
//or > 2, -3 for your extra ending
$val = $arr[count($arr)-2];
}
Should help you.
$second_last = count($array) - 3;
$value = $array[$second_last];
$arrayLen=count($arr);
echo $arr[$arrayLen-2];
Yet another alternative:
echo current(array_slice($data, -3, 1));

Categories