Searching an array inside an array - php

I have an array, inside an array. I'd like to search the values in that nestled array.
Currently I'm trying:
foreach($retval as $k=>$v){
if (is_array($v)){
$search = array_search($group_name,$v);
}
}
if($search == FALSE) {
// Nothing was found
} else {
// results found
}
Once this has been done, I simply want to perform an action depending on whether a result was found or not in the search.
How do you do this?

You need to change $search = array_search($group_name,$v); to:
$search = false;
foreach($retval as $k=>$v){
if(array_search($group_name,$v)){
$search = true;
}
}
Basically, you only want to assign true to search if you found the value you are looking for. Otherwise you could overwrite search's value with false. For example, say search is in element 0, you set it to true. Then in element 1 the element is not there, you then set search to false.
Furthermore, if you only care about knowing it's there, you could add break; after $search = true; to stop searching the array.

Related

how to limit access when one or more data on array have duplicate

i'm sorry if my english not good.
I have a problem in my code. how I can stop access when in my array have duplicate. I mean, when one or more data in array have duplicate, user must repeat input from first page. and when array have not duplicate, user can access next page.
this is my code I have try.
$no_id=array('100100','100200','100300','100200','100200','100100');
$array = array();
foreach ($no_id as $key => $value)
{
if(isset($array[$value]))
{
$array[$value] += 1;
} else
{
$array[$value] = 1;
}
}
foreach ($array as $alert => $n)
{
if($n >= 2)
{
header('location:../../home');
} else
{
header('location:../../questionnair');
}
}
but when found the duplicate data (in array 100100 have two data and 100200 three data), the system still bring user to access questionnair page, not home.
thanks for helping.
I think the main problem is that you should always use exit() after using header() with location, otherwise the page will continue to execute.
This would still cause a problem though if the first value was a unique value as the first loop would always exit;.
You could fix this (only ever call header() if the value is > 2, then the default of all are unique is after the loop), but an alternative is to use array_count_values() which counts how many each value exists in the list and then use max() to find the most occurring one, then test against that...
$no_id=array('100100','100200','100300','100200','100200','100100');
$n = max(array_count_values($no_id));
if($n >= 2)
{
header('location:../../home');
exit;
} else
{
header('location:../../questionnair');
exit;
}
Update:
An alternative and slightly quicker version would be to use your original first loop, but as soon as it detects the value is already set, then it can stop working and just return then...
$no_id=array('100100','100200','100300','100200','100200','100100');
$array = array();
foreach ($no_id as $key => $value)
{
if(isset($array[$value]))
{
header('location:../../home');
exit;
} else
{
$array[$value] = 1;
}
}
header('location:../../questionnair');
exit;
If you just need to check if the array does have dupliate, you can use array_unique and compare the new array with the old array. If the arrays are not the same, it means there are duplicates.
With code:
$no_id = array('100100','100200','100300','100200','100200','100100');
$new_array = array_unique($no_id);
if (count($no_id) == count($new_array)) {
// 2 arrays have same number of items => they are equal => no duplicates
$redirect = "questionnair.php";
} else {
// 2 arrays have different number of items => they are not equal => duplicates
$redirect = "home.php";
}
header("location: {$redirect}");
NOTE
You have to redirect to an another PHP page (ex. home.php and not just home).
First of all, it's simplier to use array_unique function, which will remove all duplicated values.
After that you can make checks, if nothing was changed, then there is no duplicated items.
Like this:
$no_id=array('100100','100200','100300','100200','100200','100100');
$no_id_unique = array_unique($no_id);
if(count($no_id)===count($no_id_unique)){
header('location:../../questionnair');
}else{
header('location:../../home');
}
exit();
Next thing that you using ../ in path which means go to parent directory.
I don't know your environment, but must likely it's a bad idea.
According to documentation it's better to specify full url of page where user must be forwarded:
header("Location: http://www.example.com/home/");
Also, please be aware, that you need to prevent all others output from a script, especcially before the header() call. Read more here.
you can use foreach (array_unique($no_id) as $key => $value)
You can use array_count_values for this, not tested, but could be like:
$counts = array_count_values($no_id);
$duplicate = false;
foreach ($no_id as $value) {
if ($counts[$value] > 1) {
$duplicate = true;
break; // found a duplicate, no need to check further.
}
}
if ($duplicate === true) {
header('location:../../home');
} else {
header('location:../../questionnair');
}
Using array_flip()
$no_id = array('100100','100200','100300','100200','100200','100100');
$no_id_unique = array_flip($no_id);
if(count($no_id) === count($no_id_unique)){
header('location:../../questionnair');
}else{
header('location:../../home');
}
exit();

PHP verify array elements are all empty

I need to ensure that all the elements in my array are empty strings to process an action. The way I am currently doing it is incrementing a variable each time an element is an empty string. Then I check the value of that variable against a certain requirement N. If N is met, the action is processed. Below is the snippet of the code that checks for empty strings. I am not sure if this is the best way to do it and think there has to be a better way to do it because basically I am hard coding that value N. Can anybody else suggest another approach?
function checkErrorArray($ers) {
$err_count = 0;
foreach ($ers as &$value) {
if ($value == '') {
$err_count++;
}
}
return $err_count;
}
Why don't you do:
function areAllEmpty($ers) {
foreach ($ers as &$value) {
//if a value is not empty, we return false and no need to continue iterating thru the array
if (!empty($value)) return false;
}
//if got so far, then all must be empty
return true;
}
It will not have to run through the whole array if a non-empty value is found.
You could also do a shorter version:
function areAllEmpty($ers) {
$errs_str = implode('', $ers);//join all items into 1 string
return empty($errs_str);
}
Hope this helps.
Just filter it and if it is empty then ! will return true if not empty it will return false:
return !array_filter($ers);
Or if you actually need the count of empty elements then:
return count(array_diff($ers, array_filter($ers)));

php in_array search too broad, need array entry not just string value

I have the following code that looks through the category array and finds the existence of the string 'Events'. I want only it to trigger if there is NOT an array entry called "Events", something like for example 'News and Events' is fine. I'm sure it's a simple solution but I can't seem to find it. Any thoughts?
$cat_check = get_the_category_list(',');
$cat_check_array = explode(",",$cat_check);
if(!(in_array("Events", $cat_check_array, true))) {
//Do Something
}
Example of categories in $cat_check
$cat_check = "News and Events","Category 1","Category 2";
$cat_check = "Events";
The only thing I don't want this bit of code to trigger on is the existence of an array entry "Events", anything else like "News and Events" is perfectly fine.
in_array() does straight equality testing. It's not ever been capable of doing partial/substring matches. Bite the bullet and use a loop:
foreach($array as $haystack) {
if (strpos($haystack, $needle) !== FALSE) {
... text is present
}
}
Would array_reduce be what you are looking for?
function in_array_ext($value, $arr) {
return array_reduce($arr, function ($carry, $item) use ($value) {
return (strpos($item, $value) !== false) || $carry;
}, false);
}
if (!in_array_ext("Events", $cat_check_array)) {
// Do something, "Events" does not present in the array values
}
You can easily perform that with the preg_grep function :
Return array entries that match the pattern
Code example :
$search = "Events"; // whatever you want
$result = preg_grep('~' . preg_quote($search, '~') . '~', $cat_check_array);
Here, we use the preg_quote function on the search variable to prevent uses of the ~ symbol

How to check if the variable of XPath is empty?

In some cases the below XPath does not have any value.
$place = extractNodeValue('div[contains(#class, "fn")]/a', $xPath);
I tried to find if it does not contain with the empty function and $place='' without luck.
Is there any way to make this possible?
Using var_dump I get NULL.
The definition of the function extractNodeValue() is missing in your code-example. Therefore this can not be really answered, that is like a black box.
According to the var_dump in your question you need to compare if $place is identical to NULL, that is $place === NULL or is_null($place).
Example (verbose):
$place = extractNodeValue('div[contains(#class, "fn")]/a', $xPath);
$hasValue = $place !== NULL;
if ($hasValue)
{
# do something with $place
}
If you're referring to your extractNodeValue() function from your question xPath or operator two compute more than two? currently it may return:
NULL - if your XPath query doesn't match anything;
Empty string ('') - if the XPath matches some nodes, but the attribute you provided or the node value is indeed an empty string, since both DOMElement::getAttribute and DOMNode::getValue return strings.
Anyhow, PHP empty considers both scenarios as empty, so without an example to see how you're using it, there's no way to tell where you ran out of luck.
If you don't want to distinguish the 2 cases above, my advise would be to standardize the function's output by changing it to:
function extractNodeValue($query, $xPath, $attribute = null) {
$node = $xPath->query("//{$query}")->item(0);
if (!$node) {
return '';
}
return $attribute ? $node->getAttribute($attribute) : $node->nodeValue;
}
With this a simple validation as follow should work:
$place = extractNodeValue('div[contains(#class, "fn")]/a', $xPath);
if (!empty($place)) {
// do something
} else {
// do something else
}

PHP: A better way of getting the first value in an array if it's present

Here's my code:
$quizId = '';
foreach ($module['QuizListing'] as $quizListing) {
if ($quizListing['id']) {
$quizId = $quizListing['id'];
break;
}
}
Is there a better way of doing this?
What you're doing is reasonable assuming that:
multiple quiz listings appear; and
not all of them have an ID.
I assume from your question that one of both of these is not true. If you want the first quiz listing then do this:
$listing = reset($module['quizListing']);
$quizId = $listing['id'];
The reset() function returns the first element in the array (or false if there isn't one).
This assumes every quiz listing has an ID. If that's not the case then you can't get much better than what you're doing.
Slight change:
$quizId = '';
foreach ($module['QuizListing'] as $quizListing) {
if (isset($quizListing['id'])) {
$quizId = $quizListing['id'];
break;
}
}
to answer if this array is coming from a database you probably have to better to filter your query not to include those row at first place
something like
SELECT * from Quiz WHERE id <> 0
this would give you an array usable without any other processing.
$quiz = array_shift($module['QuizListing']);
if (null != $quiz) {
echo "let's go";
}
Using array_key_exists you can check if the key exists for your array. If it exists, then assign it to whatever you want.
if (array_key_exists('id', $quizListing)) {
$quizId = $quizListing['id'];
}

Categories