in_array function fails for checking an object with multiple properties - php

If the $gymnast object is not in the $gymnasts array, I add it to my table. However, when I add the same object to the array, in_array() fails (returns 1) and the duplicate object is added to the array. Using print_r, I saw that the $gymnast object is clearly the same as the first element in the $gymnasts array, so why is this happening? How do I fix this?
$gymnasts array
Array ( [0] => Gymnast Object ( [name] => Nastia Liukin [age] => 27 [height] => 5' 3" [olympicYear] => 2008 [medalCount] => 5 [image] => nastia.jpg ) [1] => Gymnast Object ( [name] => Shawn Johnson [age] => 25 [height] => 4' 11" [olympicYear] => 2008 [medalCount] => 4 [image] => shawn.jpg ))
$gymnast object
Gymnast Object ( [name] => Nastia Liukin [age] => 27 [height] => 5' 3" [olympicYear] => 2008 [medalCount] => 5 [image] => nastia.jpg )
index.php
<?php
function isDuplicateEntry($gymnast, $gymnasts) {
foreach ($gymnasts as $gym) {
$gymArr = get_object_vars($gym);
$gymnastArr = get_object_vars($gymnast);
if (count(array_diff($gymnastArr, $gymArr)) == 0) { //gymnast object already exists in array
return true;
}
else {
return false;
}
}
}
//Add gymnast when press add submit button
if(isset($_POST['add'])){
//Set gymnast array to all gymnasts in data.txt
$gymnasts = read_file($filename);
//If form has valid elements & no duplicats, add to data.txt file
if($valid_name && $valid_age && $valid_feet && $valid_inches && $valid_olympicYear && $valid_medalCount && $valid_image){
$gymnast = get_gymnast_from_form();
//Make sure gymnast is not null
if(!is_null($gymnast)){
//Prevent from adding duplicates
if(!isDuplicateEntry($gymnast, $gymnasts)){
//Write task to file
write_file($filename, $gymnast);
//Add gymnast to global var gymnasts array
$gymnasts[] = $gymnast;
echo'<div class ="title">Gymnast Added!</div>';
}
}
}
?>

You cannot use in_array for multidimensional objects straight away. You will have to loop them to find out the match.
Use array_intersect to check if the array is present in another array.
$flag = 0;
foreach ($gymnasts as $gym {
if (count(array_intersect($gymnast, $gym)) == count($gym)) {
echo 'It is present.';
$flag = 1;
break;
}
}
if ($flag == 0) {
echo 'Not present in array';
}
You can also use array_diff to match arrays.
$flag = 0;
foreach ($gymnasts as $gym) {
if (count(array_diff($gymnast, $gym)) == 0) {
echo 'It is present.';
$flag = 1;
break;
}
}
if ($flag == 0) {
echo 'Not present';
}
array_intersect
array_diff
ideone link array_intersect
ideone link array_diff

You can use array_filter with count:
$is_in_array = count(array_filter($gymnasts, function($member) use ($gymnast) {
return $member == $gymnast;
})) > 0;

Related

Filtering objects using a string input from search bar

I'm trying to make a filter/search function for items from 1 page only, so far I've tried many different methods and all of them did not work properly. I had the idea to search for a string through the whole page, the commented parts are my attempts to make it work, sadly I had no luck as of yet. I've tried array_search, but this is an object from what I understand, I had no luck with strpos too.
What I'm trying to do:
WP_User Object (
[data] => stdClass Object (
[ID] => 68
[user_login] => name
[user_pass] =>
[user_nicename] => name-nicename
[user_email] => name#mail.com
[user_url] =>asdf
[user_registered] => 2019
[user_activation_key] =>
[user_status] => 0
[display_name] => KAROLIS DEDELE
)
[ID] => 68
[caps] => Array ( [asdf] => 1 )
[cap_key] => wp_capabilities
[roles] => Array ( [0] => )
[allcaps] => Array (
[edit_posts] => 1
[level_0] => 1
[read_private_events] => 1
[read_private_locations] => 1
[] => 1
)
[filter] =>
[site_id:WP_User:private] => 1
)
I'm trying to get the [display_name] => KAROLIS DEDELE part.
here's the code which puts out all post parts.
$str is the text which you enter in the search bar on the page. Other elements seem to be self explanatory.
$elements_list=array();
foreach($users as $user) {
$show_user=0;
//display_name => name surname
if ($_GET) {
if (isset($_GET[$user->roles[0]])) $show_user=1;
} else $show_user=1;
if ($show_user==1) {
array_push($elements_list,array($user,0));
}
/*
if ($user->$display_name == $str) {
echo 'it works';
else 'Sorry that user does not exist';
}
*/
//$display_names=array_search('display_name', $str);
print_r($user);
$organisation = get_user_meta($user->ID,$mv_org_name,true);
if ($_GET) {
if (!isset($_GET['organization'])) $set_organization=0;
}
if ($organisation!='' && $set_organization==1) {
array_push($elements_list,array($user,1));
}
/*
foreach ($user as $display_name) {
$found=0;
if($display_name == $str){
$show_user=1;
$found=1;
if($found==1){
echo $str,' found ';
}
//print_r($display_name);
}
else {
$show_user=0;
echo ' nerasta ';
//print_r($str);
}
}
*/
Please let me know what I'm doing wrong, or maybe the functions I'm using are incorrect
The first thing you're doing wrong is that you access the wrong data in the wrong way. You should do it by searching against $user->data->display_name instead of $user->$display_name.
Also, you may use array_filter instead of a loop:
$elements_list = array_filter($users, static function(WP_User $user) use ($str, $mv_org_name) {
if (!empty($str) && stripos($user->data->display_name, $str) === false) {
return false;
}
if (!empty($_GET)) {
if (!isset($_GET[$user->roles[0]]) {
return false;
}
if ((int) ($_GET['organization'] ?? 0) === 1 &&
get_user_meta($user->ID, $mv_org_name, true) === ''
) {
return false;
}
}
return true;
});

how to check if a name exist multiple times in an array

i need to check if there is the name john more than 3 times in the names key within the following array that contains 4 different sub arrays
Array
(
[0] => Array
(
[total] => 4.2
[name] => john
)
[1] => Array
(
[total] => 2
[name] => john
)
[2] => Array
(
[total] => 3
[name] => adam
)
[3] => Array
(
[total] => 1.5
[name] => john
)
)
i was using mysql first but i prefer to use php instead
You can do the following:
$counts = array_count_values(array_column($array,"name"));
Then to check if there's 3 people called "john" :
if (isset($counts["john"]) && $counts["john"] >= 3) {
//Do stuff
} else {
//Do different stuff
}
To find check all peole not called "john" you can either change the above to as #Andreas suggests:
if (isset($counts["john"]) && (count($array) - $counts["john"]) > 3) {
//Do stuff
} else {
//Do different stuff
}
Alternatively do:
$notJohn = count(array_filter($array, function ($element) {
return $element["name" != "john";
}));
if ($notJohn >= 3) ...
A function like this will do the work
I have roughly written it in mobile.
$occurence = 0;
function a() {
for($x = 0; $x < 4; $x++) {
for($y = 0; $y < 2; $y++) {
if (array[$x][$y] === "John") {
$occurence++;
}
}
}
if($occurence > 3) {
return false;
}
else {
return true;
}
}
Here, $namesArray in an array with repeated value in it.Target is to count how many time exist each value in array.
$namesArray =
array("John","Mark","John","Dan","Hasib","Milon","Samad","Milon","John");
$newArray = array();
foreach($namesArray as $name){
if(isset($newArray[$name])){
$newArray[$name]++;
}else{
$newArray[$name] = 1;
}
}
According to code here is output :
Array(
[John] => 3
[Mark] => 1
[Dan] => 1
[Hasib] => 1
[Milon] => 2
[Samad] => 1
)

Compare Array key value with the given name

Hi i am working on some array operations with loop.
I want to compare array key value with the given name.
But i am unable to get exact output.
This is my array :
Array
(
[0] => Array
(
[label] =>
[value] =>
)
[1] => Array
(
[label] => 3M
[value] => 76
)
[2] => Array
(
[label] => Test
[value] => 4
)
[3] => Array
(
[label] => Test1
[value] => 5
)
[4] => Array
(
[label] => Test2
[value] => 6
)
)
This is my varriable which i need to compare : $test_name = "Test2";
Below Code which i have tried :
$details // getting array in this varriable
if($details['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
But every time its returns NotFound.
Not getting what exactly issue.
#Manthan Dave try with array_column and in_array() like below:
<?php
if(in_array($test_name, array_column($details, "label"))){
return $test_name;
}
else
{
return "NotFound";
}
$details is a multidimensional array, but you are trying to access it like a simple array.
You need too loop through it:
foreach ($details as $item) {
if($item['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
}
I hope your array can never contain a label NotFound... :)
You have array inside array try with below,
if($details[4]['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
Although foreach loop should work but if not try as,
for($i=0; $i<count($details); $i++){
if($details[$i]['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
}
Traverse your array like this,
array_walk($array, function($v) use($test_name){echo $v['label'] == $test_name ? $test_name : "NotFound";});
Just use in_array and array_column without use of foreach loop as
if (in_array($test_name,array_column($details, 'label')))
{
return $test_name;
}
else
{
return "NotFound";
}
You need to check only the if condition like below because else meet at first time it will return the "notfound" then it will not execute.
$result = 'NotFound';
foreach ($details as $item) {
if($item['label'] == $test_name)
{
$result = $test_name;
}
}
return $result;
or
$result = 'NotFound';
if (in_array($test_name,array_column($details, 'label')))
{
$result = $test_name;
}
return $result;

Create array from another array if values are same

I have the following array -
Array
(
[31] => Array
(
[0] => 3
[1] => 3
)
[33] => Array
(
[0] => 2
[1] => 1
)
)
Now for the key 31 both of the elements has same value ie 3 but not for the key 33. So I am trying to create another array which will look like.
Array
(
[31] => same
[33] => notsame
)
That means if a key from multidimensional array has got all the values same then it will have the text 'same' else 'notsame'
My code-
foreach($subvaluesArr as $k1=>$v1) //$subvaluesArr is the multidimensional array here
{
foreach($v1 as $k2=>$v2)
{
if($v1[$k2] = $v1[$k2+1])
{
$newArr[$k1] = 'same';
}
else
{
$newArr[$k1] = 'notsame';
}
}
}
echo '<pre>';
print_r($newArr);
echo '</pre>';
And the output is showing 'notsame' for both keys.
Array
(
[31] => notsame
[33] => notsame
)
Any help is highly appreciated.
When you run this snippet, you will get this error
Notice: Undefined index: 2 in /in/bcqEH on line 14
See https://3v4l.org/bcqEH
This is because the code tries to compare first and second, and it tries to compare second and third element. But this third element doesn't exist. This means the comparison fails and sets the value to notsame.
To fix this, you could just compare the first two elements, e.g.
foreach ($subvaluesArr as $k1 => $v1) {
if ($v1[0] == $v1[1]) {
$newArr[$k1] = 'same';
} else {
$newArr[$k1] = 'notsame';
}
}
When you really have more than two elements, you might try array_unique
foreach ($subvaluesArr as $k1 => $v1) {
$u = array_unique($v1);
if (count($u) == 1) {
$newArr[$k1] = 'same';
} else {
$newArr[$k1] = 'notsame';
}
}
You have to break; loop after running the if-else condition.
example :
foreach($subvaluesArr as $k1=>$v1) //$subvaluesArr is the multidimensional array here
{
foreach($v1 as $k2=>$v2)
{
if($v1[$k2] === $v1[$k2+1])
{
$newArr[$k1] = 'same';
}
else
{
$newArr[$k1] = 'notsame';
}
break;
}
}
cant comment so I write it as answer. In your loop when you hit last element of an array, you ask
if($v1[$k2] == $v1[$k2+1])
where $v1[$k2+1] is "undefined" as you are out of bounds. So this last element is always false and you end up with "notsame"

PHP - how to compare value of arrays in dynamic way?

Ok, I have following 'challange';
I have array like this:
Array
(
[0] => Array
(
[id] => 9
[status] => 0
)
[1] => Array
(
[id] => 10
[status] => 1
)
[2] => Array
(
[id] => 11
[status] => 0
)
)
What I need to do is to check if they all have same [status].
The problem is, that I can have 2 or more (dynamic) arrays inside.
How can I loop / search through them?
array_diff does support multiple arrays to compare, but how to do it? :(
Which ever loop I have tried, or my Apache / browser died - or I got completely bogus data back.
You could just put the problem apart to make it easier to solve.
First get all status items from your array:
$status = array();
forach($array as $value)
{
$status[] = $value['status'];
}
You now have an array called $status you can see if it consists of the same value always, or if it has multiple values:
$count = array_count_values($status);
echo count($count); # number of different item values.
Try this code:
$status1 = $yourArray[0]['status'];
$count = count($yourArray);
$ok = true;
for ($i=1; $i<$count; $i++)
{
if ($yourArray[$i]['status'] !== $status1)
{
$ok = false;
break;
}
}
var_dump($ok);
function allTheSameStatus( $data )
{
$prefStatus = null;
foreach( $data as $array )
{
if( $prefStatus === null )
{
$prefStatus = $array[ 'status' ];
continue;
}
if( $prefStatus != $array[ 'status' ] )
{
return false;
}
}
return true;
}
I'm not sure what you want as output but you could iterate through the outer array and create an output array that groups the inner arrays by status:
$outputArray = array();
foreach ($outerArray as $an_array) {
$outputArray[$an_array['status']][] = $an_array['id'];
}

Categories