most common values in a multidemensional array - php

My question is maybe repetitive but I really find it hard. (I have read related topics)
This is the array :
Array
(
[0] => Array
(
[legend] => 38440
)
[1] => Array
(
[bestw] => 9765
)
[2] => Array
(
[fiuna] => 38779
)
[3] => Array
(
[adam] => 39011
)
[4] => Array
(
[adam] => 39011
)
[5] => Array
(
[adam] => 39011
)
)
I have tried many ways to handle this array and find out the most common value. The result I expect is "adam"
$countwin = array_count_values($winnernames);
$maxwin = max($countwin);
$mostwinner = array_keys($countswin, $maxwin);
EDIT : My array is like this array("A"=>"1" , "B"=>"2" , "A"=>"1") it should return A is the most common

How about iterating your array and counting the values you've got?
$occurences = array();
foreach ($data as $row) {
foreach ($row as $key => $score) {
if (empty($occurences[$key])) {
$occurences[$key] = 1;
} else {
$occurences[$key]++;
}
}
}
and then sorting that
arsort($occurences);
and grabbing the first element of the sorted array
$t = array_keys($occurences);
$winner = array_shift($occurences);

You may try this code. A brute force method indeed. But a quick search made me to find this an useful one:
function findDuplicates($data,$dupval) {
$nb= 0;
foreach($data as $key => $val)
if ($val==$dupval) $nb++;
return $nb;
}
EDIT : Sorry, I misinterpreted your question! But it might be the first hint of finding the one with maximum counter.

Related

Count the item from an array in PHP

How can I count in a multidimensional array the number of element with a special condition ?
Array
(
[0] => Array
(
[item] => 'Banana'
)
[1] => Array
(
[item] => 'Banana'
)
[2] => Array
(
[item] => 'Cherry'
)
[3] => Array
(
[item] => 'Apple'
)
)
For example, for this array I should find 2 for Banana.
Si I tried:
$i=0;
foreach($array as $arr) {
if($arr[item]=='Banana') { $i++; }
}
Is there a better solution please ?
Thanks.
Method 1:
Using built-in functions - array_column and array_count_values:
print_r(array_count_values(array_column($arr,'item')));
Method 2:
Using foreach with simple logic of making your fruit as key and its count as value:
$arr = [
["item"=>"Banana"],
["item"=>"Banana"],
["item"=>"Cherry"],
["item"=>"Apple"]
];
$countArr = [];
foreach ($arr as $value) {
$item = $value['item'];
if(array_key_exists($item, $countArr)) // If key exists, increment its value
$countArr[$item]++;
else // Otherwise, assign new key
$countArr[$item] = 1;
}
print_r($countArr);
Final result in both case would be:
Array
(
[Banana] => 2
[Cherry] => 1
[Apple] => 1
)
So when you want Banana's count, you can get it like this:
echo $countArr['Banana'];
Use array_count_values(), it is pretty straight forward:
foreach($array as $arr) {
$new[] = $arr['item'];
}
print_r(array_count_values($new));
On a side note, there isn't anything wrong with your approach, unless you want to count all values. Also on a side note, I think you'll find a foreach() will eek out a slightly faster time than array_column(), especially on a large array.

Create new array based on unique keys

I am struggling with an array that I need to convert into a new array based on the unique array keys. My current result looks like below. Each array represent just a part of the desired result (pivot) where I need a [menu_name], [menu_url] and [menu_target] as result and when the next array begins with the same keys, etc. So the way I see it to achieve this is to construct a new array, each time an array_key_exist in the array. But i am unable to achieve this.
Array
(
Array
(
[menu_name] => Contact
)
Array
(
[menu_url] => /contact
)
Array
(
[menu_target] => _blank
)
Array
(
[menu_name] => Home
)
Array
(
[menu_url] => /home
)
Array
(
[menu_target] => _self
)
)
The desired array I want to create looks like this:
Array
(
[0] => Array
(
[menu_name] => Contact,
[menu_url] => /contact,
[menu_target] => _blank
)
[1] => Array
(
[menu_name] => Home,
[menu_url] => /home,
[menu_target] => _blank
)
)
Here is my code so far (incomplete):
$result = array();
foreach($array as $option => $value)
{
$result[$value->option_key] = $value->option_value;
$new_array = array();
if(array_key_exist($value->option_key, $new_array))
{
// here is where I get stuckā€¦.
print_r($new_array);
}
}
I hope some one can get me in the right direction to further complete the code with the desired result.
You can use a var you increment each time key already exists :
$result = array();
$i = 0;
foreach($array as $option => $value)
{
if ( array_key_exists($value->option_key, $result[$i]) ) $i++;
$result[$i][$value->option_key] = $value->option_value;
}
Another way, is if the current batch of keys are complete, go to the next one and fill up the next one. Example:
$values = array(array('menu_name' => 'Contact'),array('menu_url' => '/contact'),array('menu_target' => '_blank'),array('menu_name' => 'Home'),array('menu_url' => '/home'),array('menu_target' => '_self'),);
$new_values = array();
$x = 0;
$columns = array_unique(array_map(function($var){
return key($var);
}, $values));
foreach($values as $value) {
$current_key = key($value);
$new_values[$x][$current_key] = reset($value);
if(array_keys($new_values[$x]) == $columns) $x++;
}
echo '<pre>';
print_r($new_values);
Sample Demo
Provided your answer is always grouped by threes, as posted in your example.
This is an alternative method to djidi's answer incase you wanted to see it done with silly loops.
$new = array_chunk($a, 3);
$d = array();
foreach($new as $i => $group) {
foreach($group as $index => $item) {
foreach($item as $name=>$val) {
$d[$i][$name] = $val;
}
}
}
Which returns:
Array
(
[0] => Array
(
[menu_name] => Contact
[menu_url] => /contact
[menu_target] => _blank
)
[1] => Array
(
[menu_name] => Home
[menu_url] => /home
[menu_target] => _self
)
)
Example Demo

How can I filter a multidimentional array for duplicates?

I have an array set up like:
Array (
[0] => Array ( [stage] => biometrics [applicant_id] => b79a4c6ea30611e3a3160675fe500303 )
[1] => Array ( [stage] => biometrics [applicant_id] => b79a4c6ea30611e3a3160675fe600303 )
[2] => Array ( [stage] => biometrics [applicant_id] => b79a4c6ea30611e3a3160675fe700303 )
[3] => Array ( [stage] => biometrics [applicant_id] => b79a4c6ea30611e3a3160675fe800303 )
[4] => Array ( [stage] => biometrics_queue [applicant_id] => b79a4c6ea30611e3a3160675fe900303 )
)
First, I want to check to see if there are any duplicate applicant_id's then I need to check the stages for the duplicates. If the applicant_id are the same, but stages are different, they are ok, If the applicant_id's are the same and stages are either the same (biometrics & biometrics) or if it is (biometrics and biometrics_queue) I need to delete that entry from the array.
Not sure how to do this.
.
So here is what I have so far. It works, but there are a lot of loops going on, don't wanna end up using too many resources or getting into an infinite loop...Does anyone see anything wrong with what I'm doing?
First, I used a function called convert stages, so that if there is anything that is a stage name and then _queue appended to the end, it changes it to just the stage name.
foreach ($timer_entry as $key => $value){
$timer_entry[$key]['stage'] = convert_stages($timer_entry[$key]['stage']);
}
Then I have a foreach inside of a for, checking for applicant_id's that might be the same:
for ($i = 0; $i < count($timer_entry); $i++) {
foreach ($timer_entry as $key => $value){
if ($key == $i) {
continue;
}
else {
if ($timer_entry[$key]['applicant_id'] == $timer_entry[$i]['applicant_id']) {
if ($timer_entry[$key]['stage'] == $timer_entry[$i]['stage']) {
unset($timer_entry[$key]);
}
}
}
}
}
If they are the same, I unset them.
I didn't test it, but I think this might do the trick:
$array = array_map('unserialize', array_unique(array_map('serialize', $array)));
How about:
foreach( $myArray as $index => $element )
if (isset($tmp[$element['applicant_id']][str_replace('_queue','',$element['stage'])])
unset($myArray[$index]);
else
$tmp[$element['applicant_id']][str_replace('_queue','',$element['stage'])] = true;

Getting multi dimensional array to create new arrays based on index value

I am having a terrible time getting this to work I have been struggling with it for a couple hours now. Can someone please help me? I have included a fiddle.
I believe my problem is in this string:
$$salesAndOwner[$i]["$salesAndOwner[$i]".$l] = $salesAndOwner[$i.$l][$param] = $values[$l];
Basically I have the following multidimensional array:
[sales] => Array
(
[FirstName] => Array
(
[0] => salesFirst1
[1] => salesFirst2
)
[LastName] => Array
(
[0] => salesLast1
[1] => salesLast2
)
)
[decisionmaker] => Array
(
[FirstName] => Array
(
[0] => dmFirst1
[1] => dmFirst2
)
[LastName] => Array
(
[0] => dmLast1
[1] => dmLast2
)
)
)
I need this to be reorganized like I did with the following array:
Array
(
[additionallocations0] => Array
(
[Address] => Address1
[State] => State1
)
[additionallocations1] => Array
(
[Address] => Address2
[State] => State2
)
)
Here is the original:
Array
(
[additionallocations] => Array
(
[Address] => Array
(
[0] => Address1
[1] => Address2
)
[State] => Array
(
[0] => State1
[1] => State2
)
)
This is how I reorganize the above array:
if(isset($_POST['additionallocations'])) {
$qty = count($_POST['additionallocations']["Address"]);
for ($l=0; $l<$qty; $l++)
{
foreach($_POST['additionallocations'] as $param => $values)
{
$additional['additionallocations'.$l][$param] = $values[$l];
}
}
And this is what I am using for the sales and decisionmaker array. If you notice I have an array that contains sales and decisionmaker in it. I would like to be able to sort any future arrays by just adding its primary arrays name. I feel I am close to solving my problem but I can not get it to produce right.
$salesAndOwner = array(0 => "sales", 1 => "decisionmaker");
for($i = 0; $i < 2; $i++){
$qty = count($_POST[$salesAndOwner[$i]]["FirstName"]);
for ($l=0; $l<$qty; $l++)
{
foreach($_POST[$salesAndOwner[$i]] as $param => $values)
{
$$salesAndOwner[$i]["$salesAndOwner[$i]".$l] = $salesAndOwner[$i.$l][$param] = $values[$l];
}
}
}
In the above code I hard coded 'sales' into the variable I need it to make a variable name dynamically that contains the sales0 decisionmaker0 and sales1 decisionmaker1 arrays so $sales and $decisionmaker
I hope this makes sense please let me know if you need any more info
Let's break it down. Using friendly variable names and spacing will make your code a lot easier to read.
Remember. The syntax is for you to read and understand easily. (Not even just you, but maybe future developers after you!)
So you have an array of groups. Each group contains an array of attributes. Each attribute row contains a number of attribute values.
PHP's foreach is a fantastic way to iterate through this, because you will need to iterate through (and use) the index names of the arrays:
<?php
$new_array = array();
// For each group:
foreach($original_array as $group_name => $group) {
// $group_name = e.g 'sales'
// For each attribute in this group:
foreach($group as $attribute_name => $attributes) {
// $attribute_name = e.g. 'FirstName'
// For each attribute value in this attribute set.
foreach($attributes as $row_number => $attribute) {
// E.g. sales0
$row_key = $group_name . $row_number;
// if this is the first iteration, we need to declare the array.
if(!isset($new_array[$row_key])) {
$new_array[$row_key] = array();
}
// e.g. Array[sales0][FirstName]
$new_array[$row_key][$attribute_name] = $attribute;
}
}
}
?>
With this said, this sort of conversion may cause unexpected results without sufficient validation.
Make sure the input array is valid (e.g. each attribute group has the same number of rows per group) and you should be okay.
$salesAndOwner = array("sales", "decisionmaker");
$result = array();
foreach ($salesAndOwner as $key) {
$group = $_POST[$key];
$subkeys = array_keys($group);
$first_key = $subkeys[0];
foreach ($group[$first_key] as $i => $val) {
$prefix = $key . $i;
foreach ($subkeys as $subkey) {
if (!isset($result[$prefix])) {
$result[$prefix] = array();
}
$result[$prefix][$subkey] = $val;
}
}
}
DEMO
Try
$result =array();
foreach($arr as $key=>$val){
foreach($val as $key1=>$val1){
foreach($val1 as $key2=>$val2){
$result[$key.$key2][$key1] = $val2;
}
}
}
See demo here

Replace value in array based on other array

I would like to replace the value of a multidimensional array if a corrosponding array contains a certain value.
Basically, I have two multidimensional arrays. One contains the actual data and the other contains a yes/no for whether the first array should be modified.
Is there any way to do this:
if optB[i][i] contains 'yes'
then opt[i][i] = '<strong>'.opt[i][i].'</strong>';
I'm lost as to whether this is even possible. Any help would be greatly appreciated -- thank you!
Thank you for the help so far. Here is the array:
[opt] => Array
(
[0] => Array
(
[0] => value1
[1] => value2
)
[1] => Array
(
[0] => value3
[1] => value4
)
)
[optB] => Array
(
[0] => Array
(
[0] => on
)
[1] => Array
(
[1] => on
)
)
Those are some interesting arrays because usually numeric arrays always have a 0. I imagine you may have some different key combination so I think this is the best "future-proof" method:
foreach ($optB as $i => $optB2) {
foreach ($optB2 as $j => $val) {
if ($val) {
$opt[$i][$j] = '<strong>' . $opt[$i][$j] . '</strong>';
}
}
}
It is possible. You can do this:
for ($i = 0; $i < count(opt); $i++) {
if ($optB[$i][$i] == "yes")
opt[$i][$i] = '<strong>'.opt[$i][$i].'</strong>';
}
It can be written like this:
if (strpos($optB[$i][$i], 'yes'))
$opt[$i][$i] = '<strong>'.$opt[$i][$i].'</strong>';
Something along these lines:
foreach ($opt as $i => &$arr) {
foreach ($arr as $j => &$val) {
if ($optB[$i][$j]) {
$val = "<strong>$val</strong>";
}
}
}
Modify as needed.

Categories