Compare values from two Arrays PHP - php

I have two Arrays with Objects in it. I want to compare each property of the array with each other.
function compare ($array1, $array2)
{
$uniqueArray = array();
for ($i = 0; $i < count($array1); $i++)
{
for ($j = 0; $j < count($array2); $j++)
{
if(levenshtein($array1[$i]->getCompany(), $array2[$j]- >getCompany() > 0 || levenshtein($array1[$i]->getCompany(), $array2[$j]->getCompany()) < 3))
{
//add values to $unqiueArray
}
}
}
print_r($uniqueArray);
}
I'm not sure if my code is right. The iteration over the arrays and then the compare is that the right approach?
Object Properties:
private $_company;
private $_firstname;
private $_sirname;
private $_street;
private $_streetnumber;
private $_plz;
private $_place;
All prperties are strings.

You shouldn't use for (expr1; expr2; expr3) for iterating arrays; it's better to use foreach (array_expression as $value)
Also, you are comparing every element on array1 with every element on array2, but if there's a match you compare them again later.
Try something like this
foreach($array1 as $k1 => $v1) {
foreach($array2 as $k2 => $v2) {
if(your_condition()) {
$uniqueArray[] = $v1;
unset($array2[$k2])
}
}
}
Or maybe do some research on array_uintersect or array_walk

In the if, one parenthesis is mis-placed, which probably is the main problem and does unexpected results.
levenstein is not a trivial operation, you shouldn't do it two times just to compare it, it's better to store the result in a variable.
Without more details about the input and expected output, it's impossible to help you more.
Here is the code fixed.
function compare ($array1, $array2)
{
$uniqueArray = array();
for ($i = 0; $i < count($array1); $i++)
{
for ($j = 0; $j < count($array2); $j++)
{
$companyNamesLevenstein = levenshtein($array1[$i]->getCompany(), $array2[$j]->getCompany());
if($companyNamesLevenstein > 0 || $companyNamesLevenstein < 3)
{
$uniqueArray [] = $array1[$i];
}
}
}
print_r($uniqueArray);
}

Related

PHP Radix Sort Algorithm - Type conversion ok?

This is a function I wrote for a Radix Sort in PHP.
It works for all cases where the array is populated with numbers greater than 0.
function radix_sort($arr) {
// Find the number of passes needed to complete the sort
$passes = strlen((string)max($arr));
$buckets = [];
// Start the passes
for($i = 1; $i <= $passes; $i++) {
// Create - reinitialize some buckets
for ($b = 0; $b <= 9; $b++) {
$buckets[$b] = [];
}
for ($j = 0; $j < count($arr); $j++) {
// Drop into the proper bucket based on the significant digit
$numStr = (string)$arr[$j];
if (strlen($numStr) < $i) {
$bucketsIndex = 0;
} else {
$bucketsIndex = $numStr[strlen($numStr) - $i];
}
array_push($buckets[$bucketsIndex], $arr[$j]);
}
// Repopulate our array by pulling out of our buckets
$k = 0;
foreach ($buckets as $bucket) {
foreach ($bucket as $value) {
$arr[$k] = $value;
$k++;
}
}
}
return $arr;
}
I feel like there's too much type converting going on. Is it ok to be doing this? If I wanted to pull the Nth digit from a large number, is there a better way in PHP?
You could convert all the value to string before the function, and then revert back to int at the end:
function radix_sort($arr) {
$arr = array_map ('strval', $arr) ;
$passes = strlen(max($arr)) ; // Should still work since all values are numeric
/* Do your stuff... */
return array_map ('intval', $arr) ;
}
Then in your inner loop you could store the length (I don't really know the complexity of strlen in PHP but I assumed it is not O(1)):
for ($j = 0; $j < count($arr); $j++) {
// Drop into the proper bucket based on the significant digit
$numStr = $arr[$j];
$numLen = strlen($numStr) ;
if ($numLen < $i) {
$bucketsIndex = 0;
} else {
$bucketsIndex = $numStr[$numLen - $i];
}
array_push($buckets[$bucketsIndex], $arr[$j]);
}
Or you could even (if you have enough memory) use an array to precompute the length:
$lengths = array_map ('strlen', $arr) ;

Searching a array in PHP, performance improvements

I've two A and B arrays, first one (A) is simple array where as the second one (B) is array of arrays. I want to find whether some element in A is equal to element in B. For doing this I'm currently doing nested loops which results in n^3 complexity. How can I improve upon this.
for ($i = 0; $i <= count($A); $i++) {
if (isset($A[$i])) {
foreach ($B as $items) {
foreach ($items as $item) {
if ($item['Column1'] == $A[$i]['Column1']) {
array_push(A, "result");
unset($A[$i]);
unset($items);
break;
}
}
}
}
}
array_walk_recursive($B, function($val) {
if (in_array($val, $A)) echo "$val is in the \$A array!";
});
Try this, array_seacrh() will remove your one foreach loop :
for ($i = 0; $i <= count($A); $i++) {
if (isset($A[$i])) {
foreach ($B as $items) {
$t = array_search($A[$i]['Column1'], $items);
array_push($A, "result");
unset($A[$i]);
unset($items[$t]);
}
}
}
when creating your arrays you can create a $lookup_A and $lookup_B arrays, where the keys are the values from the original $A and $B
Then you can do a simple loop on $lookup_A and check for if (isset($lookup_B[$lookup_A_key]))
Also in your example if(isset($A[$i])) is always true i think

How to find duplicate values in an array without using array_count_values

I am trying to find duplicated values/string in an array using for loop
<?php
$b=array('a','b','c','a','b');
$c=count($b);
$d=array();
for($i=0;$i<=($c-1);$i++)
{
for($j=1;$j<=($c-1);$j++)
{
if($b[$i]!=$b[$j])
{
$flag=1;
}
}
if($flag==1)
{
$d[$i]=$b[$i];
}
}
print_R($d);
?>
where is my mistake? I have used array $d to display non duplicate values.....
NOTE: I need to try this only with for loop - I know how to do it using array functions.
You should reverse your test, because there are almost always values, which are different from the one you're testing. And you must reset your $flag before the inner loop, otherwise it will always be true.
When you want to find unique values, you can just test against $d only. If the value is already in $d, skip it.
$c1 = count($b);
for ($i = 0; $i < $c1; $i++) {
$dup = 0;
$c2 = count($d);
for ($j = 0; $j < $c2; $j++) {
if ($b[$i] == $d[$j])
$dup = 1;
}
if (!$dup)
$d[] = $b[$i];
}
print_r($d);
If you want to find values, which don't have duplicates instead
for ($i = 0; $i < $c; $i++) {
$dup = 0;
for ($j = 0; $j < $c; $j++) {
if ($i != $j && $b[$i] == $b[$j])
$dup = 1;
}
if (!$dup)
$d[] = $b[$i];
}
function has_dupes($array){
$dupe = array();
foreach($array as $val){
if(++$dupe[$val] > 1)
return true;
}
return false;
}
could do something like this.. this would check for dupes, then u can print the uniques
Why are you making a simple task complex .. simply
$b = array('a','b','c','a','b');
var_dump(customCount($b));
Output
array (size=3)
'a' => int 2 //duplicate
'b' => int 2 //duplicate
'c' => int 1
Function Used
function customCount($array) {
$temp = array();
foreach ( $array as $v ) {
isset($temp[$v]) or $temp[$v] = 0;
$temp[$v] ++;
}
return $temp ;
}

php foreach loop

I have two arrays in my code.
Need to perform a foreach loop on both of these arrays at one time. Is it possible to supply two arguments at the same time such as foreach($array1 as $data1 and $array2 as $data2)
or something else?
If they both the same keys, you can do this:
foreach($array1 as $key=>data1){
$data2 = $array2[$key];
}
Assuming both have the same number of elements
If they both are 0-indexed arrays:
foreach ($array_1 as $key => $data_1) {
$data_2 = $array_2[$key];
}
Otherwise:
$keys = array_combine(array_keys($array_1), array_keys($array_2));
foreach ($keys as $key_1 => $key_2) {
$data_1 = $array_1[$key_1];
$data_2 = $array_2[$key_2];
}
Dont use a foreach. use a For, and use the incremented index, eg. $i++ to access both arrays at once.
Are both arrays the same size always?
Then this will work:
$max =sizeof($array);
for($i = 0; $i < $max; $i++)
array[$i].attribute
array2[$i].attribute
If the arrays are different sizes, you may have to tweak your approach. Possibly use a while.
iterative methods:
http://php.net/manual/en/control-structures.while.php
http://php.net/manual/en/control-structures.for.php
http://php.net/manual/en/control-structures.do.while.php
use for or while loop e.g.
$i = 0;
while($i < count($ar1) && $i < count($ar2) ) // $i less than both length !
{
$ar1Item = $ar1[$i];
$ar2Item = $ar2[$i];
$i++;
}
No to my knowledge with foreach, but can be easily done with for:
<?php
$cond1 = 0<count($array1);
$cond2 = 0<count($array2);
for ($i=0;$cond1 || $cond2;$i++)
{
if ($cond1)
{
// work with $array1
}
if ($cond2)
{
// work with $array2
}
$cond1 = 0<count($array1);
$cond2 = 0<count($array2);
}
?>

How do I set the foreach loop to start at the last array?

How do I set my foreach loop to start looking at the last entry of the array then each loop will go backwards instead of forward?
Thank you.
You could just reverse the array:
$reverse = array_reverse($array, true); // true to preserve keys
foreach($reverse as $key => $value) { /* etc. */ }
Or if you're sure that the array contains only numeric keys, this is probably faster:
for($i = count($array) - 1; $i >= 0; $i--) {
/* etc. */
}
foreach(array_reverse($array, true) as $key=>$value)
The array_reverse function will reverse an array.
You could do this:
$values = array();
$max = count($values);
foreach($i = $max; $i > 0; $i--) {
$key = $values[$i];
// do something with the key
}

Categories