checking if an array has values also in another array - php

I have an array which is structured like this:
funActivities(array)
0(array)
Activity(array)
id 4
name walks
1(array)
Activity(array)
id 5
name cycling
2(array)
Activity(array)
id 6
name sand pit
and then another like:
activities
0(array)
id 4
name walks
1(array)
id 6
name sand pit
I want to compare the two arrays and end up with an array which only contains the activities from the 1st array which don't appear in the 2nd array. So in this case I'd end up with just cycling in the array. It's in the first array, but not the second.
Whats the best way to do that?

i made a php function that works for you...
i hope this can help. of course there are some things i could do better but for this szenario it works
<?php
$funActivities[0]['Activity']['id'] = 4;
$funActivities[0]['Activity']['name'] = "walks";
$funActivities[1]['Activity']['id'] = 5;
$funActivities[1]['Activity']['name'] = "cycling";
$funActivities[2]['Activity']['id'] = 6;
$funActivities[2]['Activity']['name'] = "sand pit";
$activities[0]['id'] = 4;
$activities[0]['name'] = "walks";
$activities[1]['id'] = 6;
$activities[1]['name'] = "sand pit";
function compareArray($needle,$haystack)
{
$tmpArray = $haystack;
foreach($needle as $n)
{
$s1 = $n['id'].$n['name'];
$count = 0;
foreach($haystack as $h)
{
$s2 = $h['Activity']['id'].$h['Activity']['name'];
if( $s1 == $s2)
{
unset($tmpArray[$count]);
}
$count++;
}
}
return array_values($tmpArray);
}
$arr = compareArray($activities,$funActivities);
echo "<pre>";
print_r($arr);
echo "</pre>";
?>

Related

PHP array get the different number

I have the following array:
$array = [2,2,5,2,2];
I would like to get the number which is different from the others, for example all the numbers are 2 except the number 5. So Is there anyway to get the different number using any array method or better solution? My solution is:
$array = [2,2,5,2,2];
$array1 = [4,4,4,6,4,4,4];
$element = -1;
$n = -1;
$count = 0;
for($i=0; $i<count($array1); $i++) {
if($element !== $array1[$i] && $element !== -1 & $count==0) {
$n = $array1[$i];
$count++;
}
$element = $array1[$i];
}
dd($n);
You can use array_count_values for group and count same value like:
$array = [2,2,5,2,2];
$countarray = array_count_values($array);
arsort($countarray);
$result = array_keys($countarray)[1]; // 5
Since you only have two numbers, you will always have the number with the least equal values ​​in second position
Reference:
array_count_values
array_keys
A small clarification, for safety it is better to use arsort to set the value in second position because if the smallest number is in first position it will appear as the first value in the array
Sorting Arrays
You can user array_count_values which returns array with item frequency.
Then use array_filter to filter out data as follow:
$arrayData = [2,2,2,5];
$filterData = array_filter(array_count_values($arrayData), function ($value) {
return $value == 1;
});
print_r($filterData);
Inside array_filter(), return $value == 1 means only get the data with 1 frequency and thus filter out the other data.
<?php
function UniqueAndDuplicat($array){
$counts = array_count_values($array);
foreach ($counts as $number => $count) {
print $number . ' | ' . ($count > 1 ? 'Duplicate value ' : 'Unique value ') . "\n";
}
}
$array1 = [2,2,5,2,2];
$array2 = [4,4,4,6,4,4,4];
UniqueAndDuplicat($array1);
//output: 2 | duplicate value 5 | Unique value
UniqueAndDuplicat($array2);
//output: 4 | duplicate value 5 | Unique value
?>
Use this function to reuse this you just call this function and pass an Array to this function it will give both unique and duplicate numbers.
If you want to return only Unique number then use the below code:
<?php
function UniqueAndDuplicat($array){
$counts = array_count_values($array);
foreach ($counts as $number => $count) {
if($count == 1){
return $number;
}
}
}
$array1 = [2,2,5,2,2];
$array2 = [4,4,4,6,4,4,4];
echo UniqueAndDuplicat($array1); // 5
echo "<br>";
echo UniqueAndDuplicat($array2); // 6
?>

PHP replace every 2nd

<?php
$fact_BB = array("[start]", "[mid]", "[end]");
$fact_HTML = array("<tr><td class='FactsTableTDOne'><p>", "</p></td><td class='FactsTableTDTwo'><p>", "</p></td></tr>");
$str_Facts = str_replace($fact_BB, $fact_HTML, $row['facts']);
echo $str_Facts;
?>
Is it possible to switch between 2 $fact_HTML?
1. $fact_HTMLone = "code";
2. $fact_HTMLtwo = "code";
3. $fact_HTMLone = "code";
4. $fact_HTMLtwo = "code";
5. $fact_HTMLone = "code";
etc. etc.
Sure. With $fact_HTML[0], $fact_HTML[1], $fact_HTML[n] etc. you can access your $fact_HTML array. Using modulo of 2 you can always access every 2nd (or first and second) elements of the array.
To check if the element is even or odd you can use:
if ($n % 2 == 0) {
//even element
} else {
//odd element
}
Also you can use Modulo 2 ($n % 2) as n to iterate through the array in the same way. You can also combine both variants.
$count = 10; //number of facts
for ($n = 0; $n < $count; $n++) {
$fact_HTML[$n % 2] = $fact;
}
What you want to achieve is a replace of some strings. I'd suggest a solution like this:
<?php
$str_Facts = $row['facts'];
$replacements = array( "[start]" => "<tr><td class='FactsTableTDOne'><p>",
"[mid]" => "</p></td><td class='FactsTableTDTwo'><p>",
"[end]" => "</p></td></tr>" );
foreach ($replacements as $repkey => $repval) {
$str_Facts = str_replace($repkey,$repval,$str_Facts);
}
echo $str_Facts;
?>
If you want to go on with your approach, you'd loop through the arrays (you have to ensure that the both arrays have the same number of elements).
<?php
$str_Facts = $row['facts'];
for ($i=0;$i<count($fact_BB);$i++) {
//if you want to switch every uneven, do this:
if ($i%2!=0) continue;
$str_Facts = str_replace($fact_BB[$i],$fact_HTML[$i],$str_Facts);
}
echo $str_Facts;
?>

PHP How to merge two arrays inside a loop

I have a problem with the code below which is driving me crazy. What I want to do is to compare a given array with a sentence and then I need to know their position in the sentence for each occurrence, by now the script only return just one array, for example with the positions in which the name Marta is found inside the sentence. I trying to merge all the results in just one array but I'm a bit lost at the moment. I hope someone can give me some clues to make it. Best regards.
$sentence = 'Maria is Maria and Marta is Marta.';
$womennames = array("Maria","Marta");
function poswomen($chain, $words){
foreach($words as $findme){
$valida_existe = substr_count($chain,$findme);
$largo_encuentra = strlen($findme);
$posicion = array();
for($x=0; $x < strlen($chain); $x++){
$posic_x = strpos($chain, $findme, $x);
if($posic_x >= 0){
$posicion[] = $posic_x;
$x = $x+$largo_encuentra;
}
}
$posicion = array_unique($posicion);
$posicion = implode(",",$posicion);
}
return $posicion;
}
poswomen($sentence, $womennames);
print_r (poswomen($sentence, $womennames));
Just like barmar has said, your position keeps resetting you need to set it outside, from that , then add the currently found position so that it will carry on. Consider this example:
$sentence = 'Maria is Maria and Marta is Marta.';
$women_names = array('Maria', 'Marta');
$pos = 0;
$positions = array();
foreach($women_names as $name) {
while (($pos = strpos($sentence, $name, $pos))!== false) {
$positions[$name][] = $pos;
$pos += strlen($name);
}
$positions[$name] = implode(', ', $positions[$name]);
}
echo '<pre>';
print_r($positions);
echo '</pre>';
Sample Output:
Array
(
[Maria] => 0, 9
[Marta] => 19, 28
)

PHP how to output the top array_count_values value from array?

I have a table that I need to find "top trusted builder" from, Trusts are separated by " ; ", So I need to pull all the data, explode the usernames, order and count them, and Im stuck on finally outputting the top username form the array, I have posted up the full segment of PHP, because im sure there has to be a much better way of doing this.
<?php
$GTB = $DBH->query('SELECT builders from griefprevention_claimdata where builders <> ""');
$GMCB->setFetchMode(PDO::FETCH_ASSOC);
$buildersarray = array();
while($row = $GTB->fetch()) {
$allbuilders = explode(";", $row['builders']);
for($i = 0; $i < count($allbuilders); $i++)
{
$buildersarray[] = $allbuilders[$i];
}
}
echo "<pre>";
print_r(array_count_values(array_filter($buildersarray)));
echo "</pre>";
?>
Outputs
Array
(
[username1] => 4
[username2] => 1
[username3] => 1
)
You can return the array from the array_count_values command into a new array called $topbuilders, and then echo out the current (first) record:
$topbuilders = array_count_values(array_filter($buildersarray));
echo current(array_keys($topbuilders)).', Rank = '.current($topbuilders);
current() will return the first item in an associative array.
Instead of using array_count_values() it would be better to use the names as the key to a frequency array:
$GTB = $DBH->query('SELECT builders from griefprevention_claimdata where builders <> ""');
$result = array();
while (($builders = $GTB->fetchColumn()) !== false) {
foreach (explode(";", $builders) as $builder) {
if (isset($result[$builder])) {
$result[$builder]++;
} else {
$result[$builder] = 1;
}
}
// sort descending based on numeric comparison
arsort($result, SORT_NUMERIC);
echo "Name = ", key($result), " Count = ", current($result), "\n";

PHP: Shuffle array, so no value is like the correspondent one

There is an array with names, for example:
$donalds_nephews = array('Huey', 'Dewey', 'Louie');
array
(
[0] => Huey
[1] => Dewey
[2] => Louie
)
I want to shuffle this array, but ensure that no value of the original array has the same key as the shuffled one.
$donalds_nephews_shuffled = shuffle($donalds_nephews);
This could result in 6 possible permutations:
Huey, Dewey, Louie
Huey, Louie, Dewey
Dewey, Louie, Huey
Dewey, Huey, Louie
Louie, Dewey, Huey
Louie, Huey, Dewey
1st, 2nd, 4th and 5th must not be the result.
What's the best way to do so? It's for Secret Santa.
Shuffle the original array, then make a copy of it and shift all entries one over, then match the two back together to get your matches.
It's for Secret Santa.
Then start with a better algorithm. Currently you seem to be inferring that the key is a present giver and the value a present receiver (or vice versa). This then entails the additional check (and possible re-iteration of the shuffling) to ensure that nobody ends up giving a present to themselves.
But what if you just consider it as an ordered list of names, such that each entry gives to the next person on the list:
$victims=array('Huey', 'Dewey', 'Louie');
shuffle($victims);
$giver='';
foreach($victims as $receiver) {
if ($giver) print "$giver gives to $receiver\n";
$giver=$receiver;
}
$receiver=array_shift($victims);
print "$giver gives to $receiver\n";
just cause i need this for my secret santa :)
<?php
function compareArrays($original, $shuffled){
for($i = 0; $i < count($original); $i++ ){
if($original[$i] == $shuffled[$i]){
return false;
}
}
return true;
}
$donalds_nephews = array('Huey', 'Dewey', 'Louie','Igor','Stephan');
//avoid loops
for($j = 0; $j < 50; $j++){
$shuffled = $donalds_nephews;
shuffle($shuffled);
$good = compareArrays($donalds_nephews, $shuffled);
if($good) break;
}
if($good){
echo "here we go!\n";
foreach($shuffled as $k => $v){
echo "$k => $v \n";
}
}
else {
echo "try again \n";
}
?>
Don't make this complicated by trying to put all of this into one function.
Here's your pseudocode:
$givers = array( 'Huey', 'Dewey', 'Louie' );
$getters = $givers;
foreach ( $givers as $giver ) {
do {
pick a random $getter from $getters;
} until $getter <> $giver;
delete $getter from $getters;
print "$giver gives to $getter\n";
}
It is an old question, but you asked for the best way, so how about this?
function santaYates($array) {
$returnArray = array_values($array); // Cause we need a clean numeric array
$secure = false;
for($i = count($returnArray) - 1; $i > 0; $i--) {
$r = mt_rand(0, $i-1); //subtract 1 from $i to force a new place.
$tmp = $returnArray[$i];
$returnArray[$i] = $returnArray[$r];
$returnArray[$r] = $tmp;
}
return $returnArray;
}
It works very similar to the Fisher-Yates shuffle.
There is just one little difference:
We permit to use the same key, so every entry will get a new place (cause we substract 1 from $i when we do the randomize step).
Working Demo

Categories