Skip to content
Advertisement

Compare values from a single array with multiple series of arrays, then echo the result

With the following script I am able to calculate the frequency of every number from 10 different arrays, then echoes the result sorting the numbers in frequency classes (ex. values that appear one time : x, y, z , values that appear two times : a, b, c, ….etc.)

<?php $set1 = ['23', '11', '52', '33', '1', '4'];
$set2 = ['66', '70', '55', '8', '22', '1'];
$set3 = ['38', '21', '52', '51', '53', '9'];
$set4 = ['14', '31', '54', '5', '73', '39'];
$set5 = ['10', '3', '22', '59', '73', '39'];
$set6 = ['22', '13', '4', '5', '73', '39']
$set7 = ['40', '3', '22', '5', '13', '30'];
$set8 = ['88', '53', '4', '25', '71', '19'];
$set9 = ['10', '30', '49', '25', '73', '46'];
$set10 = ['10', '3', '4', '5', '73', '11'];

$mergedArray = array_merge($set1, $set2, $set3, $set4, $set5, $set6, $set7, $set8, $set9, $set10);
echo 'Values that appear 1 time: ' . implode(', ', array_keys(getRepeatedNumber($mergedArray, 1))) . '<br>';
echo 'Values that appear 2 times: ' . implode(', ', array_keys(getRepeatedNumber($mergedArray, 2))) . '<br>';
echo 'Values that appear 3 times: ' . implode(', ', array_keys(getRepeatedNumber($mergedArray, 3))) . '<br>';
echo 'Values that appear 4 times: ' . implode(', ', array_keys(getRepeatedNumber($mergedArray, 4))) . '<br>';
echo 'Values that appear 5 times: ' . implode(', ', array_keys(getRepeatedNumber($mergedArray, 5))) . '<br>';
function getRepeatedNumber($mergedArray, $requiredCount)
{
$counts = array_count_values($mergedArray);
$requiredResult = array_filter($counts, function ($value) use ($requiredCount) {
    return $value == $requiredCount;
});
return $requiredResult;}

My problem : I would like to calculate the frequency and echo the result of an extra array of numbers that should be compared with the actual set of arrays of my script.

For example : If I have

$extraset = ['1', '4', '52'] ;

i would like to

  • check how many times those numbers appear in the $set1 to $set10 arrays
  • echo the result sorting the numbers in frequency classes like now.

but I don’t understand how to compare the $extraset (i am a real newbie..!)

thanks for your help !

Advertisement

Answer

You can think of the problem as a conversion problem. You are converting numbers to their frequency and vice versa. array_count_values sets up a table of conversions as an array. The keys of the array, gives the numbers to convert and their values their frequency.

So start off with building up the merged arrays:

$set1 = ['23', '11', '52', '33', '1', '4'];
$set2 = ['66', '70', '55', '8', '22', '1'];
$set3 = ['38', '21', '52', '51', '53', '9'];
$set4 = ['14', '31', '54', '5', '73', '39'];
$set5 = ['10', '3', '22', '59', '73', '39'];
$set6 = ['22', '13', '4', '5', '73', '39']
$set7 = ['40', '3', '22', '5', '13', '30'];
$set8 = ['88', '53', '4', '25', '71', '19'];
$set9 = ['10', '30', '49', '25', '73', '46'];
$set10 = ['10', '3', '4', '5', '73', '11'];

$mergedArray = array_merge($set1, $set2, $set3, $set4, $set5, $set6, $set7, $set8, $set9, $set10);

Next set up the conversion table:

$frequencies = array_count_values($mergedArray);

Then set up the inverse lookup of this table (keys are counts, values are numbers):

$inverse_frequencies = [];
foreach ($frequencies as $number => $count) {
    $inverse_frequencies[$count][] = $number;
}

Sort this, so the keys (counts) are ascending for display purposes:

ksort($inverse_frequencies);

And display them:

foreach ($inverse_frequencies as $count => $numbers_array) {
    echo "Values that appear $count times: " . implode(', ', $numbers_array) . '<br>';
}

This method is more general and flexible than the one you gave.

Next we take the $extraset array and loop through to find the frequency of each element and display it:

$extraset = ['1', '4', '52'] ;

foreach ($extraset as $element) {
    $frequency = $frequencies[$element]??0;
    echo "Extraset element '$element' appears $frequency times<br>";
}

Note the use of of the null coalescing operator ?? just in case we can’t find the number in the frequency list.

EDIT

You could improve on the way the sets are handled, by pushing each new set into an array and then merging (ideally you would put this in a function):

$sets = [];
$sets[] = ['23', '11', '52', '33', '1', '4'];
$sets[] = ['66', '70', '55', '8', '22', '1'];
$sets[] = ['38', '21', '52', '51', '53', '9'];
$sets[] = ['14', '31', '54', '5', '73', '39'];
$sets[] = ['10', '3', '22', '59', '73', '39'];
$sets[] = ['22', '13', '4', '5', '73', '39'];
$sets[] = ['40', '3', '22', '5', '13', '30'];
$sets[] = ['88', '53', '4', '25', '71', '19'];
$sets[] = ['10', '30', '49', '25', '73', '46'];
$sets[] = ['10', '3', '4', '5', '73', '11'];

$mergedArray = [];
foreach ($sets as $set) {
    $mergedArray = array_merge($mergedArray, $set);
}

That allows you to have an indexed set of arrays ($sets), the ones with higher indexes are newer.

You can then search the $sets array in reverse to find the most recent instance of a number:

$reverse_sets = array_reverse($sets);

foreach ($extraset as $element) {
    foreach ($reverse_sets as $index => $set) {
        if (in_array($element, $set)) {
            $actual_index = count($reverse_sets)-$index-1;
            echo "Extraset element '$element' is in set $actual_index<br>";
            break;
        }
    }
}

You need to fixup the $index because reversing the array re-indexes it (the keys are not kept).

You need break so that as soon as you find a value, you move on to the next value.

I’ll leave it up to you how you handle elements which are not found.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement