Getting the most repeated values in an array [duplicate] - php

This question already has answers here:
PHP get the item in an array that has the most duplicates
(2 answers)
Closed 1 year ago.
I have an array of numbers like this:
$array = array(1,1,1,4,3,1);
How do I get the count of most repeated value?

This should work:
$count=array_count_values($array);//Counts the values in the array, returns associatve array
arsort($count);//Sort it from highest to lowest
$keys=array_keys($count);//Split the array so we can find the most occuring key
echo "The most occuring value is $keys[0][1] with $keys[0][0] occurences."

I think array_count_values function can be useful to you. Look at this manual for details : http://php.net/manual/en/function.array-count-values.php

You can count the number of occurrences of values in an array with array_count_values:
$counts = array_count_values($array);
Then just do a reverse sort on the counts:
arsort($counts);
Then check the top value to get your mode.
$mode = key($counts);

If your array contains strings or integers only you can use array_count_values and arsort:
$array = array(1, 1, 1, 4, 3, 1);
$counts = array_count_values($array);
arsort($counts);
That would leave the most used element as the first one of $counts. You can get the count amount and value afterwards.
It is important to note that if there are several elements with the same amount of occurrences in the original array I can't say for sure which one you will get. Everything depends on the implementations of array_count_values and arsort. You will need to thoroughly test this to prevent bugs afterwards if you need any particular one, don't make any assumptions.
If you need any particular one, you'd may be better off not using arsort and write the reduction loop yourself.
$array = array(1, 1, 1, 4, 3, 1);
/* Our return values, with some useless defaults */
$max = 0;
$max_item = $array[0];
$counts = array_count_values($array);
foreach ($counts as $value => $amount) {
if ($amount > $max) {
$max = $amount;
$max_item = $value;
}
}
After the foreach loop, $max_item contains the last item that appears the most in the original array as long as array_count_values returns the elements in the order they are found (which appears to be the case based on the example of the documentation). You can get the first item to appear the most in your original array by using a non-strict comparison ($amount >= $max instead of $amount > $max).
You could even get all elements tied for the maximum amount of occurrences this way:
$array = array(1, 1, 1, 4, 3, 1);
/* Our return values */
$max = 0;
$max_items = array();
$counts = array_count_values($array);
foreach ($counts as $value => $amount) {
if ($amount > $max) {
$max = $amount;
$max_items = array($value);
} elif ($amount = $max) {
$max_items[] = $value;
}
}

$vals = array_count_values($arr);
asort($vals);
//you may need this end($vals);
echo key($vals);
I cant remember if asort sorts asc or desc by default, you can see the comment in the code.

<?php
$arrrand = '$arr = array(';
for ($i = 0; $i < 100000; $i++)
{
$arrrand .= rand(0, 1000) . ',';
}
$arrrand = substr($arrrand, 0, -1);
$arrrand .= ');';
eval($arrrand);
$start1 = microtime();
$count = array_count_values($arr);
$end1 = microtime();
echo $end1 - $start1;
echo '<br>';
$start2 = microtime();
$tmparr = array();
foreach ($arr as $key => $value);
{
if (isset($tmparr[$value]))
{
$tmparr[$value]++;
} else
{
$tmparr[$value] = 1;
}
}
$end2 = microtime();
echo $end2 - $start2;
Here check both solutions:
1 by array_count_values()
and one by hand.

<?php
$input = array(1,2,2,2,8,9);
$output = array();
$maxElement = 0;
for($i=0;$i<count($input);$i++) {
$count = 0;
for ($j = 0; $j < count($input); $j++) {
if ($input[$i] == $input[$j]) {
$count++;
}
}
if($count>$maxElement){
$maxElement = $count;
$a = $input[$i];
}
}
echo $a.' -> '.$maxElement;
The output will be 2 -> 3

$arrays = array(1, 2, 2, 2, 3, 1); // sample array
$count=array_count_values($arrays); // getting repeated value with count
asort($count); // sorting array
$key=key($count);
echo $arrays[$key]; // get most repeated value from array

String S;
Scanner in = new Scanner(System.in);
System.out.println("Enter the String: ");
S = in.nextLine();
int count =1;
int max = 1;
char maxChar=S.charAt(0);
for(int i=1; i <S.length(); i++)
{
count = S.charAt(i) == S.charAt(i - 1) ? (count + 1):1;
if(count > max)
{
max = count;
maxChar = S.charAt(i);
}
}
System.out.println("Longest run: "+max+", for the character "+maxChar);

here is the solution
class TestClass {
public $keyVal;
public $keyPlace = 0;
//put your code here
public function maxused_num($array) {
$temp = array();
$tempval = array();
$r = 0;
for ($i = 0; $i <= count($array) - 1; $i++) {
$r = 0;
for ($j = 0; $j <= count($array) - 1; $j++) {
if ($array[$i] == $array[$j]) {
$r = $r + 1;
}
}
$tempval[$i] = $r;
$temp[$i] = $array[$i];
}
//fetch max value
$max = 0;
for ($i = 0; $i <= count($tempval) - 1; $i++) {
if ($tempval[$i] > $max) {
$max = $tempval[$i];
}
}
//get value
for ($i = 0; $i <= count($tempval) - 1; $i++) {
if ($tempval[$i] == $max) {
$this->keyVal = $tempval[$i];
$this->keyPlace = $i;
break;
}
}
// 1.place holder on array $this->keyPlace;
// 2.number of reapeats $this->keyVal;
return $array[$this->keyPlace];
}
}
$catch = new TestClass();
$array = array(1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 1, 2, 3, 1, 1, 2, 5, 7, 1, 9, 0, 11, 22, 1, 1, 22, 22, 35, 66, 1, 1, 1);
echo $catch->maxused_num($array);

Related

All combinations of r elements from given array php

Given an array such as the following
$array = ('1', '2', '3', '4', '5', '6', '7');
I'm looking for a method to generate all possible combinations, with a minimum number of elements required in each combination r. (eg if r = 5 then it will return all possible combinations containing at least 5 elements)
Combinations of k out of n items can be defined recursively using the following function:
function combinationsOf($k, $xs){
if ($k === 0)
return array(array());
if (count($xs) === 0)
return array();
$x = $xs[0];
$xs1 = array_slice($xs,1,count($xs)-1);
$res1 = combinationsOf($k-1,$xs1);
for ($i = 0; $i < count($res1); $i++) {
array_splice($res1[$i], 0, 0, $x);
}
$res2 = combinationsOf($k,$xs1);
return array_merge($res1, $res2);
}
The above is based on the recursive definition that to choose k out n elements, one can fix an element x in the list, and there are C(k-1, xs\{x}) combinations that contain x (i.e. res1), and C(k,xs\{xs}) combinations that do not contain x (i.e. res2 in code).
Full example:
$array = array('1', '2', '3', '4', '5', '6', '7');
function combinationsOf($k, $xs){
if ($k === 0)
return array(array());
if (count($xs) === 0)
return array();
$x = $xs[0];
$xs1 = array_slice($xs,1,count($xs)-1);
$res1 = combinationsOf($k-1,$xs1);
for ($i = 0; $i < count($res1); $i++) {
array_splice($res1[$i], 0, 0, $x);
}
$res2 = combinationsOf($k,$xs1);
return array_merge($res1, $res2);
}
print_r ($array);
print_r(combinationsOf(5,$array));
//print_r(combinationsOf(5,$array)+combinationsOf(6,$array)+combinationsOf(7,$array));
A combination can be expressed as
nCr = n! / (r! - (n - r)!)
First, we determine $n as the number of elements in the array. And $r is the minimum number of elements in each combination.
$a = ['1', '2', '3', '4', '5', '6', '7']; // the array of elements we are interested in
// Determine the `n` and `r` in nCr = n! / (r! * (n-r)!)
$r = 5;
$n = count($a);
Next, we determine $max as the maximum number that can be represented by $n binary digits. That is, if $n = 3, then $max = (111)2 = 7. To do this, we first create a empty string $maxBinary and add $n number of 1s to it. We then convert it to decimal, and store it in $max.
$maxBinary = "";
for ($i = 0; $i < $n; $i++)
{
$maxBinary .= "1";
}
$max = bindec($maxBinary); // convert it into a decimal value, so that we can use it in the following for loop
Then, we list out every binary number from 0 to $max and store those that have more than $r number of 1s in them.
$allBinary = array(); // the array of binary numbers
for ($i = 0; $i <= $max; $i++)
{
if (substr_count(decbin($i), "1") >= $r) // we count the number of ones to determine if they are >= $r
{
// we make the length of the binary numbers equal to the number of elements in the array,
// so that it is easy to select elements from the array, based on which of the digits are 1.
// we do this by padding zeros to the left.
$temp = str_pad(decbin($i), $n, "0", STR_PAD_LEFT);
$allBinary[] = $temp;
}
}
Then, we use the same trick as above to select elements for our combination. I believe the comments explain enough.
$combs = array(); // the array for all the combinations.
$row = array(); // the array of binary digits in one element of the $allBinary array.
foreach ($allBinary as $key => $one)
{
$combs[$key] = "";
$row = str_split($one); // we store the digits of the binary number individually
foreach ($row as $indx => $digit)
{
if ($digit == '1') // if the digit is 1, then the corresponding element in the array is part of this combination.
{
$combs[$key] .= $a[$indx]; // add the array element at the corresponding index to the combination
}
}
}
And that is it. You are done!
Now if you have something like
echo count($combs);
then it would give you 29.
Additional notes:
I read up on this only after seeing your question, and as a newcomer, I found these useful:
Wikipedia - http://en.wikipedia.org/wiki/Combination
Php recursion to get all possibilities of strings
Algorithm to return all combinations of k elements from n
Also, here are some quick links to the docs, that should help people who see this in the future:
http://php.net/manual/en/function.decbin.php
http://php.net/manual/en/function.bindec.php
http://php.net/manual/en/function.str-pad.php
function arrToBit(Array $element) {
$bit = '';
foreach ($element as $e) {
$bit .= '1';
}
$length = count($element);
$num = bindec($bit);
$back = [];
while ($num) {
$back[] = str_pad(decbin($num), $length, '0', STR_PAD_LEFT);
$num--;
}
//$back[] = str_pad(decbin(0), $length, '0', STR_PAD_LEFT);
return $back;
}
function bitToArr(Array $element, $bit) {
$num = count($element);
$back = [];
for ($i = 0; $i < $num; $i++) {
if (substr($bit, $i, 1) == '1') {
$back[] = $element[$i];
}
}
return $back;
}
$tags = ['a', 'b', 'c'];
$bits = arrToBit($tags);
$combination = [];
foreach ($bits as $b) {
$combination[] = bitToArr($tags, $b);
}
var_dump($combination);
$arr = array(1,2,3,4,5,6);
$check_value =[];
$all_values = [];
CONT:
$result = $check_value;
shuffle($arr);
$check_value = array_slice($arr,0,3);
if(count($check_value) == 3 && serialize($check_value) !== serialize($result)){
$result = $check_value;
array_push($all_values,$result);
goto CONT;
}
print_r($all_values);

Randomly interleave/zipper flat arrays without losing element order from original arrays

I want to merge / mix two arrays together, but I want it to be randomly "mixed" however NOT shuffled. For example:
$first = [1, 2, 3, 4];
$second = [10, 20, 30, 40];
Possible desired "mixes" are:
[1, 10, 20, 30, 2, 40, 3, 4]
[10, 1, 2, 20, 30, 3, 4, 40]
[1, 2, 3, 10, 20, 4, 30, 40]
Note that if we pluck the values back out we would still have the original orders of:
1, 2, 3, 4
10, 20, 30, 40
Well, there's (yet another) one possible approach:
$arr = call_user_func_array('array_merge', array_map(null, $first, $second));
print_r($arr); // [1, 10, 2, 20, 3, 30, 4, 40];
Demo. That's apparently deterministic; for random ordering each pair should be shuffled additionally. For example:
function zipShuffle($first, $second) {
return call_user_func_array('array_merge', array_map(function($a, $b) {
return mt_rand(0, 1) ? [$a, $b] : [$b, $a];
}, $first, $second));
}
... but that obviously won't be able to churn out something like [1,2,3,10,20...]. If this is required, here's another solution:
function orderedShuffle($first, $second) {
$results = [];
$stor = [$first, $second];
$i = mt_rand(0, 1);
// switching between arrays on the fly
while (list(, $v) = each($stor[$i])) {
$results[] = $v;
$i = mt_rand(0, 1);
}
// one array is gone, now we need to add all the elements
// of the other one (as its counter left where it was)
$i = 1 - $i;
while (list(, $v) = each($stor[$i])) {
$results[] = $v;
}
return $results;
}
Demo. The last function is actually quite easy to extend for as many arrays as required.
Can you try this,
<?php
$first = array(1,2,3,4);
$second = array(10,20,30,40);
$arrayMixed=array();
$firstReverse=array_reverse($first);
$secondReverse=array_reverse($second);
$firstReverseCount = count($firstReverse);
$secondReverseCount = count($secondReverse);
foreach($firstReverse as $key=>$val) {
if ($firstReverseCount>0) {
array_push($arrayMixed, array_pop($firstReverse));
if ($secondReverseCount>0) {
array_push($arrayMixed, array_pop($secondReverse));
}
}
}
$ArrayMixeddata = array_merge($arrayMixed, $second);
echo "<pre>";
print_r($ArrayMixeddata);
echo "</pre>";
?>
Not quick ways, but them works.
// with permutations
function combineShuffleOrder($first, $second)
{
// combine into one array with alternation
$firstLen = count($first);
$secondLen = count($second);
$max = max($firstLen, $secondLen);
$result = array();
for($i=0; $i < $max; $i++) {
if ($i < $firstLen)
$result[] = $first[$i];
if ($i < $secondLen)
$result[] = $second[$i];
}
// "shuffle" with permutation
$len = count($result);
for($i=1; $i<$len; $i++) {
if (rand(1, 3) % 2 == 0) {
$tmp = $result[$i-1];
$result[$i-1] = $result[$i];
$result[$i] = $tmp;
$i++; // skip one exchange
}
}
return $result;
}
// with using "shuffle" in subarray
function combineShuffleOrder2($first, $second)
{
// combine into one array with alternation
$firstLen = count($first);
$secondLen = count($second);
$max = max($firstLen, $secondLen);
$result = array();
for($i=0; $i < $max; $i++) {
$sub = array();
if ($i < $firstLen)
$sub[] = $first[$i];
if ($i < $secondLen)
$sub[] = $second[$i];
shuffle($sub);
$result = array_merge($result, $sub);
}
return $result;
}
// with using "shuffle" in subarray if sources arrays are equals by length
function combineShuffleOrder3($first, $second)
{
$max = count($first);
$result = array();
for($i=0; $i < $max; $i++) {
$sub = array(
$first[$i],
$second[$i]
);
shuffle($sub);
$result = array_merge($result, $sub);
}
return $result;
}
$first = array(1,2,3,4);
$second = array(10,20,30,40);
print_r(combineShuffleOrder($first, $second));
print_r(combineShuffleOrder2($first, $second));
print_r(combineShuffleOrder3($first, $second));
I recommend forming a single array of the two input arrays for simpler toggling. Simply loop and consume one element from a randomly selected array and push that selection into the result array. When the pool of arrays is reduced to a single array, kill the loop and append the remaining elements of the last surviving array onto the result array.
I'll use a pool of four arrays (one which is empty from the beginning) to demonstrate that the snippet is robust enough to handle a variable number of arrays, a variable number of elements in each array, and empty arrays.
Code: (Demo)
$first = [1, 2, 3, 4];
$second = [10, 20, 30, 40];
$third = [];
$fourth = ['a', 'b'];
$pool = [$first, $second, $third, $fourth];
$result = [];
while (count($pool) > 1) {
$pullFrom = array_rand($pool);
if (!$pool[$pullFrom]) {
unset($pool[$pullFrom]);
continue;
}
$result[] = array_shift($pool[$pullFrom]);
}
var_export(array_merge($result, ...$pool));
Alternatively without array_merge() and count() calls, but it makes more iterated calls of array_shift(): (Demo)
$pool = [$first, $second, $third, $fourth];
$result = [];
while ($pool) {
$pullFrom = array_rand($pool);
if (!$pool[$pullFrom]) {
unset($pool[$pullFrom]);
continue;
}
$result[] = array_shift($pool[$pullFrom]);
}
var_export($result);
Loop this script until both arrays are done.
$j = 0;
$i = 0;
$r = rand(0, 1);
if($r == 0) {
$ret .= $array1[$i];
$i++;
} elseif($r == 1) {
$ret .= $array2[$j];
$j++;
}
Of course, you have to handle a few exceptions in this code, but it might be the route.

Cumulative array

I have this array:
$a = array(1, 2, 3, 4, 5, 7, 8, 10, 12);
Is there a function to convert this to:
$b = array(1, 1, 1, 1, 2, 1, 2, 2);
So basicaly:
$b = array ($a[1]-$a[0], $a[2]-$a[1], $a[3]-$a[2], ... ,$a[n]-$a[n-1]);
Here is the code I have so far:
$a = $c = array(1, 2, 3, 4, 5, 7, 8, 10, 12);
array_shift($c);
$d = array();
foreach ($a as $key => $value){
$d[$key] = $c[$key]-$value;
}
array_pop($d);
There isn't a built-in function that can do this for you, but you could turn your code into one instead. Also, rather than making a second array, $c, you could use a regular for loop to loop through the values:
function cumulate($array = array()) {
// re-index the array for guaranteed-success with the for-loop
$array = array_values($array);
$cumulated = array();
$count = count($array);
if ($count == 1) {
// there is only a single element in the array; no need to loop through it
return $array;
} else {
// iterate through each element (starting with the second) and subtract
// the prior-element's value from the current
for ($i = 1; $i < $count; $i++) {
$cumulated[] = $array[$i] - $array[$i - 1];
}
}
return $cumulated;
}
I think php has not a build in function for this. There are many ways to solve this, but you already wrote the answer:
$len = count($a);
$b = array();
for ($i = 0; $i < $len - 1; $i++) {
$b[] = $a[$i+1] - $a[$i];
}

PHP: Take several arrays, and make new ones based on shared indexes? [duplicate]

This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Is there a php function like python's zip?
(14 answers)
Closed 10 months ago.
So, imagine you have 3 arrays:
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
And you want to combine them into new arrays based on index:
1,6,11
2,7,12
3,8,13
4,9,14
5,10,15
What on earth could achieve this? Also, the total number of arrays is not known.
EDIT: Here's a snippet of my code so far (pulling data from a DB):
<?php
$ufSubmissions = $wpdb->get_results( $wpdb->prepare("SELECT * FROM wp_user_feedback WHERE user = '$ufUser' ORDER BY date DESC") );
$cleanedResponses = array();
foreach ($ufSubmissions as $submission) {
$cleanedResponses[] = unserialize($submission->responses);
}
array_map(null, $cleanedResponses));
?>
Doesn't seem to be working though, even $cleaned responses is an array of arrays.
Mostly like Alex Barrett's answer, but allows for an unknown number of arrays.
<?php
$values = array(
array(1,2,3,4,5),
array(6,7,8,9,10),
array(11,12,13,14,15),
);
function array_pivot($values)
{
array_unshift($values, null);
return call_user_func_array('array_map', $values);
}
print_r(array_pivot($values));
If your arrays are all the same length, you can pass as many as you want to the array_map function with null as the callback parameter.
array_map(null,
array(1, 2, 3, 4, 5),
array(6, 7, 8, 9, 10),
array(11, 12, 13, 14, 15));
The above will return the following two-dimensional array:
array(array(1, 6, 11),
array(2, 7, 12),
array(3, 8, 13),
array(4, 9, 14),
array(5, 10, 15));
This is a documented trick, so quite safe to use.
$ret = array();
for ($i =0; $i < count($input[0]); $i++){
$tmp = array();
foreach ($input as $array) {
$tmp[] = $array[$i];
}
$ret[] = $tmp;
}
Em... What's the problem? If they are equal sized, then you do
<?php
$a = array(1,2,3,4,5);
$b = array(6,7,8,9,10);
$c = array(11,12,13,14,15);
$d = array();
for ($i = 0; $i < sizeof($a); $i++) {
$d[] = array($a[$i], $b[$i], $c[$i]);
}
var_dump($d);
This is not tested, read it to get the idea instead of paste it.
The point is to put everything alltoghether in a feed and then redistribute it onto new arrays of a max length, the last one could not be full.
<?php
// initial vars
$max_size = 3; // of the new arrays
$total_array = $a + $b + $c; // the three arrays summed in the right order
$current_size = length($total_array);
$num_of_arrays = ceil($current_size / $max_size);
// redistributing
$result_arrays = array();
for($i = 0; $i < $num_of_arrays; $i++){ // iterate over the arrays
$new_array= array();
for($t = 0; $t < $max_size){
$pos = $num_of_arrays * $t + $i;
if(isset($total_array[$pos]) {
$new_array[] = $total_array[$pos];
}
}
$result_arrays[] = $new_array;
}
?>
// This takes an unlimited number of arguments and merges into arrays on index
// If there is only 1 argument it is treated as an array of arrays
// returns an array of arrays
function merge_on_indexes () {
$args = func_get_args();
$out = array();
if (count($args) == 1) for ($i = 0; isset($args[0][$i]); $i++) for ($j = 0; isset($args[0][$i][$j]); $j++) $out[$j][] = $args[0][$i][$j]; else for ($i = 0; isset($args[$i]); $i++) for ($j = 0; isset($args[$i][$j]); $j++) $out[$j][] = $args[$i][$j];
return $out;
}
// Usage examples
// Both return array('data1','data3','data5'),array('data2','data4','data6')
$arr1 = array('data1','data2');
$arr2 = array('data3','data4');
$arr2 = array('data5','data6');
$result = merge_on_indexes($arr1,$arr2);
print_r($result);
$multiDimArr = array(
array('data1','data2'),
array('data3','data4'),
array('data5','data6')
);
$result = merge_on_indexes($multiDimArr);
print_r($result);
$arr = get_defined_vars(); //gets all your variables
$arrCount = 0;
$arrOfarrs = array();
foreach($arr as $var){ //go through each variable
if(is_array($var)){ //and see if it is an array
$arrCount++; //we found another array
for($i == 0;$i < count($var); $i++){ //run through the new array
$arrOfarrs[$i][] == $var[$i]; //and add the corresponding elem
}
}
}

How do I get the highest value when using loops?

I want to get the highest value of my array.
This are the two ways when I'm working with php functions.
$a = array(1,125,1068);
1. $value = max($a);
print_r ($value);
2. asort($a);
$value = end($a);
print_r ($value);
I just couldn't figure out how to get the highest value when using loops.
You do it like this:
$highest = 0;
//if you have negative values: $highest = min($a);
foreach($a as $item){
if ($item > $highest){
$highest = $item;
}
}
Without using the max() function, you can do something like
<?php
$a = array(1,125,1068)
$max = $a[0];
for ($i = 1; $i <count($a); $i++) {
if ($a[$i] > $max) {
$max = $a[$i];
}
}
echo $max;
?>
max()
http://php.net/manual/en/function.max.php
$dd = array(50, -25, -5, 80, -40, -152, -45, 28, -455, 100, 98, -455);
$curr = '';
$max = $dd[0];
for($i = 0; $i < count($dd); $i++) {
$curr = $dd[$i];
if($curr >= $max) {
$max = $curr;
}
}

Categories