Array search not working as expected - php

I am trying to replace the value Event Id in the $fields array with the value that is mapped to (idEvent) in the $aliases array, but PHP's array_search function is returning the wrong position. Note: I am converting the values to all lower case so it should return a match, and it seems like array_search is returning a index, but it should be returning index 2 instead of index 1 since it is the third value in the $fields array.
Unfortunately, if you run the code (e.g. copy and paste it here: http://writecodeonline.com/php/), it returns the wrong value. Could someone please tell me if I am doing something wrong?
$fields = array('Host', 'OS', 'Event Id');
$aliases = array('idEvent' => 'Event ID');
foreach ($aliases as $actual => $alias){
$alias = strtolower($alias);
echo "searching fields(" . implode(',', array_map('strtolower', $fields)) . ") for $alias<br/>";
if ($position = array_search($alias, array_map('strtolower', $fields)) !== FALSE) {
echo "$alias was found at \$fields[$position]";
$fields[$position] = $actual;
}
}
Edit: I added some echo statements so you can what I am trying to do.

It's the order of operations of the if statement that's the problem. The assignment operator has lower precedence than the comparison operator, and the assignment is evaluated from the right first. So add some parenthesis:
if (($position = array_search($alias, array_map('strtolower', $fields))) !== FALSE) {
I find this easier to read:
if (in_array($alias, array_map('strtolower', $fields))) {

array_search($alias, array_map('strtolower', $fields)) !== FALSE
This is true right? Then it translates to $position = 1 and therefor you see it he found the key one but actually returns the value of the equal...
Use parenthesis or store the value of the search beforehand.

$position is getting assigned value of 1 because its the result of comparing your array_search to !== FALSE
use the test at the left side to fix the issue.
if (false !== ($position = array_search($alias, array_map('strtolower', $fields)))) {
echo "$alias was found at {$fields[$position]}";
$fields[$position] = $actual;
}

Related

Search php string - %like% sql

Right now I use stristr($q, $string) but if
$string = "one monkey can jump 66 times";
$q = "monkey 66";
I want to find out if this string contains both monkey and 66.
How can i do that?
you could use both stristr and strpos.
as it is reported in this post, the second method is faster and less memory intensive.
well, check this lines out:
// here there are your string and your keywords
$string = "one monkey can jump 66 times";
$q = "monkey 66";
// initializate an array from keywords in $q
$q = explode(" ", $q);
// for every keyword you entered
foreach($q as $value) {
// if strpos finds the value on the string and return true
if (strpos($string, $value))
// add the found value to a new array
$found[] = $value;
}
// if all the values are found and therefore added to the array,
// the new array should match the same object of the values array
if ($found === $q) {
// let's go through your path, super-man!
echo "ok, all q values are in string var, you can continue...";
}
if(stristr('monkey', $string) && stristr('66', $string)) {
//Do stuff
}
simply post your variable value by giving them a variable $monkey,$value ($monkey jumps $value) and then fetch its value
You can use the strpos() function which is used to find the occurrence of one string inside another one:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Note that the use of !== false is deliberate (neither != false nor === true will work); strpos() returns either the offset at which the needle string begins in the haystack string, or the boolean false if the needle isn't found. Since 0 is a valid offset and 0 is "falsey", we can't use simpler constructs like !strpos($a, 'are').

PHP How to get a boolean average of an array

EDIT2: This goes to the top for a reason. This question is asked wrong, but I won´t change the title, since maybe other people are caught in this misstake. I am NOT looking for an "average" - I merely want to exit with the first "false" in an array.
My though to this questions were quite twisted - therefore I asked the wrong question.
Anyway: As stated, I won´t change the question itself.
What I want to do is basically calculate something like a boolean average of an array. I know about booleans and that they are not meant to be something with an average, but please read on to see what I am doing.
My array looks like this:
$array = array(
true,
false,
true,
true
);
I now want to get an AND-operation done on this array to see, if everything in there is true or if a subfunction returned false. This is basically a list of results from different subfunctions.
This specific example then should return false, because $array[1] is false.
EDIT:
What I am looking for is a builtin PHP-function which seems not to exists. A custom implementation has the advantage to exit the iteration over this array in comparison to in_array() which might not do this.
Can you help me out, stackoverflow?
Try in_array:
$array = array(
true,
false,
true,
true
);
echo in_array(false, $array);
If one of the elements is false, it will return false otherwise it returns true.
Update: in_array, returns out of the loop as soon as the searched value is matched. The worst case I suppose is when you have a single false at the end of the searched array. The linked source are for PHP 5.3.
As far as strict checking is concerned, you can do so passing in the third parameter to in_array:
echo in_array(false, $array, true);
Come on, it would appear you didn't even try:
function checkArray(array $in)
{
foreach ($in as $bool)
{
if (!$bool)//replace with type&value checking if that's what you're after
return false;
}
return true;
}
var_dump(checkArray(array(true, false, true, true)));//false
var_dump(checkArray(array(true, true)));//true
There are, of course, a bunch of alternative ways to do what you want/need, depending on what the actual data will look like. If it's all booleans:
if (array_sum($array) != count($array))
{//true == 1, array_sum(array(true, true)) == count(array(true, true)) == 2
echo 'array contains false, or non-boolean values, like 123';
}
//for a real average:
$avg = round(array_sum($array)/count($array));
The latter will yield 1 if 50%>= of the values in the array are true, and 0 otherwise. It's then a simple matter of casting that value to a boolean to get the "average bool value":
$avg = (bool) round(
array_sum($array)/count($array)
);
or, for example:
$valsAsKey = array_flip(
array_map(
'intval',//make ints
$array
)
);
if (isset($valsAsKey[0]))
{//(int) false === 0
echo 'False in array';
}
Though these approaches don't use iteration explicitly, they do iterate the array data implicitly. A quick test did show that the simple foreach outperformed the other approaches here.
I have tried around a lot, until i came to this final result.
This is my code:
<?php
$array = array();
$array[] = true;
$array[] = false;
$array[] = false;
$array[] = true;
$array[] = false;
var_dump($array);
if((count($array)/2) <= array_sum($array)){
echo "true";
// return true
} else {
echo "false";
// return false
}
?>
it counts the elements of the array, and compares it with the COUNTED trues (array_sum($array)). Then it returns true or false, dependent on result.
You could iterate through the array and set a result to false if any vals are false;
$result = true;
foreach ($array as $v) {
if ($v===false) $result = false;
}
You can use array_filter without callback. In this case all entries of array equal to false will be removed.
if (count(array_filter($array)) == count($array)) echo 'TRUE';

array_search and destroy logic error

I am trying to search an array and see if a value is contained in it. If the value is in the array then the index of the value in the array will be passed onto be removed from the array.
The problem is array_search returns FALSE if the value is not found, but since false is a boolean it is also treated as 0. When this is passed to the unset to remove the value from the array the value at index 0 will be removed if array_search returned false.
I am fairly sure it will need to be put into an if statement but how will I handle the response if both an integer and a boolean can both be returned?
Current Code:
$pos = array_search($value, $array);
unset($array[$pos]);
PHP Doc says..
This function may return Boolean FALSE, but may also return a
non-Boolean value which evaluates to FALSE. Please read the section on
Booleans for more information. Use the === operator for testing the
return value of this function.
So you need to do like this
<?php
$arr = [1,2,3];
$pos = array_search(4, $arr);
if($pos!==false)
{
unset($arr[$pos]);
}
print_r($arr);
OUTPUT
Array
(
[0] => 1
[1] => 2
[2] => 3
)
As you can see the first index is retained.
try this
if($pos !== false)
{
// do your work to unset
}
note !== in above code
$x !== $y is True if $x is not equal to $y, or they are not of the same type
You can try this script, hope this will help you...
if(in_array($value, $array)){
$pos = array_search($value, $array);
unset($array[$pos]);
}

simple strpos() not working with "[" char, why?

why does if i do:
if(strpos("[","[rgeger]")){
echo 'hey';
}
it doesn't prints anything?
try this with a string:
function return_tags($keywords){
if($keywords){
$k_array = array();
foreach($this->check($keywords) as $key=>$value){
array_push($k_array, $value);
}
$last_array = array();
foreach($k_array as $key=>$value){
if(strpos("[", $value) && strpos("]", $value) && strlen($value) >= 2){
$value = '<span class="tag">'.$value.'</span>';
}
array_push($last_array, trim($value));
}
return $last_array;
}else{
return false;
}
}
string example
$keywords = "freignferi eiejrngirj erjgnrit [llll] [print me as tag]";
did you see any <span> element printed in html?
It looks like you swapped the arguments:
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
So if you want to know if a [ is in your string [rgeger]:
if (strpos("[rgeger]", "[") !== false) {
echo 'hey';
}
(Source: http://php.net/strpos)
The position returned is zero-indexed, so the first character is at position 0. When evaluating 0 as Boolean, it's false - so it doesn't get into the block.
Fix with this:
if (strpos('[rgeger]', '[') !== false)
Also the arguments are the wrong way round. Don't upvote this post any more; go upvote robbi's instead for spotting that one :) Eagle eyes robbi, EAGLE eyes :P
Because you have to check the return value of strpos() as it could be zero because [ it's at index zero, and zero evaluates to FALSE that's why it wouldn't enter your if block, so check that the return value it's FALSE and type boolean, not just integer zero, like this:
if(strpos("[rgeger]","[") !== false){
echo 'hey';
}
UPDATE:
The parameters were in wrong order too, the subject string comes first then the search string, I updated my code above to reflect that.
Because its wrong. Strpos give false if the condition is false.
if(strpos("[rgeger]","[") !== false){
echo 'hey';
}
Edit: I have corrected my answer. Your parameter are in the wrong order. Its:
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
Because actually strpos can return 0 see doc.
Warning
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
So you have to compare with the falsevalue directly.
if(strpos("[","[rgeger]") !== false){
echo 'hey';
}
EDIT ::
Careful.. Look at the arguments order
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
Haystack is the string input.
Needle is what you are seeking for.
if(strpos("[regeger]","[") !== false){
echo 'hey';
}

Check if all values in array are the same

I need to check if all values in an array equal the same thing.
For example:
$allValues = array(
'true',
'true',
'true',
);
If every value in the array equals 'true' then I want to echo 'all true'. If any value in the array equals 'false' then I want to echo 'some false'
Any idea on how I can do this?
All values equal the test value:
// note, "count(array_flip($allvalues))" is a tricky but very fast way to count the unique values.
// "end($allvalues)" is a way to get an arbitrary value from an array without needing to know a valid array key. For example, assuming $allvalues[0] exists may not be true.
if (count(array_flip($allvalues)) === 1 && end($allvalues) === 'true') {
}
or just test for the existence of the thing you don't want:
if (in_array('false', $allvalues, true)) {
}
Prefer the latter method if you're sure that there's only 2 possible values that could be in the array, as it's much more efficient. But if in doubt, a slow program is better than an incorrect program, so use the first method.
If you can't use the second method, your array is very large, and the contents of the array is likely to have more than 1 value (especially if the 2nd value is likely to occur near the beginning of the array), it may be much faster to do the following:
/**
* Checks if an array contains at most 1 distinct value.
* Optionally, restrict what the 1 distinct value is permitted to be via
* a user supplied testValue.
*
* #param array $arr - Array to check
* #param null $testValue - Optional value to restrict which distinct value the array is permitted to contain.
* #return bool - false if the array contains more than 1 distinct value, or contains a value other than your supplied testValue.
* #assert isHomogenous([]) === true
* #assert isHomogenous([], 2) === true
* #assert isHomogenous([2]) === true
* #assert isHomogenous([2, 3]) === false
* #assert isHomogenous([2, 2]) === true
* #assert isHomogenous([2, 2], 2) === true
* #assert isHomogenous([2, 2], 3) === false
* #assert isHomogenous([2, 3], 3) === false
* #assert isHomogenous([null, null], null) === true
*/
function isHomogenous(array $arr, $testValue = null) {
// If they did not pass the 2nd func argument, then we will use an arbitrary value in the $arr (that happens to be the first value).
// By using func_num_args() to test for this, we can properly support testing for an array filled with nulls, if desired.
// ie isHomogenous([null, null], null) === true
$testValue = func_num_args() > 1 ? $testValue : reset($arr);
foreach ($arr as $val) {
if ($testValue !== $val) {
return false;
}
}
return true;
}
Note: Some answers interpret the original question as (1) how to check if all values are the same, while others interpreted it as (2) how to check if all values are the same and make sure that value equals the test value. The solution you choose should be mindful of that detail.
My first 2 solutions answered #2. My isHomogenous() function answers #1, or #2 if you pass it the 2nd arg.
Why not just compare count after calling array_unique()?
To check if all elements in an array are the same, should be as simple as:
$allValuesAreTheSame = (count(array_unique($allValues, SORT_REGULAR)) === 1);
This should work regardless of the type of values in the array.
Update: Added the SORT_REGULAR flag to avoid implicit type-casting as pointed out by Yann Chabot
Also, you can condense goat's answer in the event it's not a binary:
if (count(array_unique($allvalues)) === 1 && end($allvalues) === 'true') {
// ...
}
to
if (array_unique($allvalues) === array('foobar')) {
// all values in array are "foobar"
}
If your array contains actual booleans (or ints) instead of strings, you could use array_sum:
$allvalues = array(TRUE, TRUE, TRUE);
if(array_sum($allvalues) == count($allvalues)) {
echo 'all true';
} else {
echo 'some false';
}
http://codepad.org/FIgomd9X
This works because TRUE will be evaluated as 1, and FALSE as 0.
You can compare min and max... not the fastest way ;p
$homogenous = ( min($array) === max($array) );
$alltrue = 1;
foreach($array as $item) {
if($item!='true') { $alltrue = 0; }
}
if($alltrue) { echo("all true."); }
else { echo("some false."); }
Technically this doesn't test for "some false," it tests for "not all true." But it sounds like you're pretty sure that the only values you'll get are 'true' and 'false'.
Another option:
function same($arr) {
return $arr === array_filter($arr, function ($element) use ($arr) {
return ($element === $arr[0]);
});
}
Usage:
same(array(true, true, true)); // => true
Answering my method for people searching in 2023.
$arr = [5,5,5,5,5];
$flag = 0;
$firstElement = $arr[0];
foreach($arr as $val){
// CHECK IF THE FIRST ELEMENT DIFFERS FROM ANY OTHER ELEMENT IN THE ARRAY
if($firstElement != $val){
// FIRST MISMATCH FOUND. UPDATE FLAG VALUE AND BREAK OUT OF THE LOOP.
$flag = 1;
break;
}
}
if($flag == 0){
// ALL THE ELEMENTS ARE SAME... DO SOMETHING
}else{
// ALL THE ELEMENTS ARE NOT SAME... DO SOMETHING
}
In an array where all elements are same, it should always be true that all the elements MUST match with the first element of the array. Keeping this logic in mind, we can get the first element of the array and iterate through each element in the array to check for that first element in the loop which does not match with the first element in the array. If found, we will change the flag value and break out of the loop immediately. Else, the loop will continue till it reaches the end. Later, outside the loop, we can use this flag value to determine if all the elements in the array are same or not.
This solution is good for arrays with definite limit of elements (small array). However, I am not sure how good this solution would be for arrays with very large number of elements present considering that we are looping through each and every element to check for the first break even point. Please use this solution at your own convenience and judgement.
$x = 0;
foreach ($allvalues as $a) {
if ($a != $checkvalue) {
$x = 1;
}
}
//then check against $x
if ($x != 0) {
//not all values are the same
}

Categories