If I have:
$mainarray = some array of things with some repeated values
$array_counted = array_count_values ($mainarray);
How can I find the maximum value in $array_counted?
(This would be the element that appeared most often in $mainarray I think. Its mostly a syntax issue as I am pretty sure I could loop it, but not sure of the syntax to use)
You can find first max value as
$main_array = array(1,2,3,4,5,6,6,6,6,6,6,6);
$max_val = max($main_array);
for find all of max vals
in php < 5.3
function findmax($val)
{
global $max_val;
return $val == $max_val;
}
$max_values_array = array_filter($main_array,'findmax');
in php >= 5.3
$max_values_array = array_filter($main_array,function($val) use ($max_val) { return $val == $max_val; });
echo count($max_values_array);
var_dump($max_values_array);
You could sort the array and take the first, respectively last item out of it, if you don't want to loop.
Since you associate the count with the values with that:
$array_counted = array_count_values ($mainarray);
You only need to sort it afterwards, and return the first key (which is the most occured element):
arsort($array_counted);
print key($array_counted); // returns first key
ok, the guy whos answer I used has deleted his comment so here is how I did it:
I used arsort($array_counted) to sort the array, while keeping index. rsort alone does not work as the result of array_count_values is an associative array. Thank you all.
Related
I'm receiving this array of objects and need to iterate over it, but the problem is that I need to get the value of the next item when its iterating, to compare the value of the current object with the next one, and if it's a different value, split this array in two.
So, I was doing it with next() php function:
//looking for the next register in the array
$next = next($finances);
//first array if exist different values
$aiuaEd = [];
//second array if exist different values
$aiua = [];
foreach ($finances as $finance) {
if ($finance->cnpj <> $next->cnpj) {
$aiua[] = $finance;
} else {
$aiuaEd[] = $finance;
}
}
This code works fine at some point, but then I got this error:
Trying to get property 'cnpj' of non-object in
I don't know why sometimes works well and sometimes don't, debugging this variables, I found that if my array have 2 objects inside only, when I'm looping over it, the $next->cnpj variable came as empty, and sometimes don't.
Can someone help me with this?
I solved it with a different approach, instead of using php next(), I first loop over this array saving the cnpj's into an array.
$cnpjs = [];
foreach($finances as $finance){
$cnpj[] = $finance->cnpj;
}
Then I use array_unique() to group this 2 differents CNPJ's and sort() to get the correct keys order.
//grouping cnpjs as unique, should exist only 2 keys
$cnpj = array_unique($cnpj);
//sort array keys to get in order
sort($cnpj);
Then I iterate over my $finances array again, but now I'm counting if this $cnpj array has more than 2 positions, which means that I have to split this data in two differents arrays.
foreach($finances as $finance){
if(count($cnpj) > 1){
if($finance->cnpj == $cnpj[1]){
$aiua[] = $finance;
}else{
$aiuaEd[] = $finance;
}
}else{
$aiuaEd[] = $finance;
}
}
I'm pretty sure that this is not the best approach for that problem, or at least the most optimized one, so I'm open for new approach's suggestions!
Just posting how I solved my problem in case anyone having the same one.
Notice that this approach is only usable because I know that will not exist more than 2 different's CNPJ's in the array.
in this foreach loop, i put a function returning the room quantity, each $sumqty['room_qty'] has different value, my question is, i want to get the highest value of $sumqty['room_qty'], do i put it in an array? how? any help will be appreciated.
<?php
foreach($reservation as $res){
$sumqty = sumqty($res['arrival'],$res['departure'],$res['room_id']);
$sumqty['room_qty'];
}
$highest = ???;
?>
i want to display the highest value by echo $highest
Yes, you can use an array. Provided $sumqty['room_qty'] is a numeric value the following will work:
$allquantities=array();
foreach($reservation as $res){
$sumqty = sumqty($res['arrival'],$res['departure'],$res['room_id']);
$allquantities[]=$sumqty['room_qty'];
}
$highest = max($allquantities);
Assuming that sumqty takes an 'arrival', 'departure' and 'room id' and returns an array with key 'room_qty' mapped to some integer:
<?php
$highest = -1000000000; //some really, really small number
foreach ($reservation as $res) {
$sumqty = sumqty($res['arrival'],$res['departure'],$res['room_id']);
if ($sumqty['room_qty'] > $highest) {
$highest = $sumqty['room_qty'];
}
}
echo $highest;
The general idea is that each time you find a higher value, you replace the previously highest value with the new higher value.
No extra array is necessary to accomplish this! Solutions that use an array to solve this problem are unnecessarily complicated. (edit: "complicated" is a poor choice of words; if an extra array is used than the program is slightly less efficient)
Get an array of all the values of $sumqty['room_qty'], $room_qty[] as in this case.
<?php
$room_qty = array();
foreach($reservation as $res){
$sumqty = sumqty($res['arrival'],$res['departure'],$res['room_id']);
$room_qty[] = $sumqty['room_qty'];
}
$highest = max($room_qty);
?>
Once you have the array you could use max() function to find the maximum value in the given array. Go through this manual you will get be clear about it.
If you have any array $p that you populated in a loop like so:
$p[] = array( "id"=>$id, "Name"=>$name);
What's the fastest way to search for John in the Name key, and if found, return the $p index? Is there a way other than looping through $p?
I have up to 5000 names to find in $p, and $p can also potentially contain 5000 rows. Currently I loop through $p looking for each name, and if found, parse it (and add it to another array), splice the row out of $p, and break 1, ready to start searching for the next of the 5000 names.
I was wondering if there if a faster way to get the index rather than looping through $p eg an isset type way?
Thanks for taking a look guys.
Okay so as I see this problem, you have unique ids, but the names may not be unique.
You could initialize the array as:
array($id=>$name);
And your searches can be like:
array_search($name,$arr);
This will work very well as native method of finding a needle in a haystack will have a better implementation than your own implementation.
e.g.
$id = 2;
$name= 'Sunny';
$arr = array($id=>$name);
echo array_search($name,$arr);
Echoes 2
The major advantage in this method would be code readability.
If you know that you are going to need to perform many of these types of search within the same request then you can create an index array from them. This will loop through the array once per index you need to create.
$piName = array();
foreach ($p as $k=>$v)
{
$piName[$v['Name']] = $k;
}
If you only need to perform one or two searches per page then consider moving the array into an external database, and creating the index there.
$index = 0;
$search_for = 'John';
$result = array_reduce($p, function($r, $v) use (&$index, $search_for) {
if($v['Name'] == $search_for) {
$r[] = $index;
}
++$index;
return $r;
});
$result will contain all the indices of elements in $p where the element with key Name had the value John. (This of course only works for an array that is indexed numerically beginning with 0 and has no “holes” in the index.)
Edit: Possibly even easier to just use array_filter, but that will not return the indices only, but all array element where Name equals John – but indices will be preserved:
$result2 = array_filter($p, function($elem) {
return $elem["Name"] == "John" ? true : false;
});
var_dump($result2);
What suits your needs better, resp. which one is maybe faster, is for you to figure out.
In the PHP manual, (array_push) says..
If you use array_push() to add one element to the array it's better to
use $array[] = because in that way there is no overhead of calling a
function.
For example :
$arr = array();
array_push($arr, "stackoverflow");
print_r($arr);
vs
$arr[] = "stackoverflow";
print_r($arr);
I don't understand why there is a big difference.
When you call a function in PHP (such as array_push()), there are overheads to the call, as PHP has to look up the function reference, find its position in memory and execute whatever code it defines.
Using $arr[] = 'some value'; does not require a function call, and implements the addition straight into the data structure. Thus, when adding a lot of data it is a lot quicker and resource-efficient to use $arr[].
You can add more than 1 element in one shot to array using array_push,
e.g. array_push($array_name, $element1, $element2,...)
Where $element1, $element2,... are elements to be added to array.
But if you want to add only one element at one time, then other method (i.e. using $array_name[]) should be preferred.
The difference is in the line below to "because in that way there is no overhead of calling a function."
array_push() will raise a warning if the first argument is not
an array. This differs from the $var[] behaviour where a new array is
created.
You should always use $array[] if possible because as the box states there is no overhead for the function call. Thus it is a bit faster than the function call.
array_push — Push one or more elements onto the end of array
Take note of the words "one or more elements onto the end"
to do that using $arr[] you would have to get the max size of the array
explain:
1.the first one declare the variable in array.
2.the second array_push method is used to push the string in the array variable.
3.finally it will print the result.
4.the second method is directly store the string in the array.
5.the data is printed in the array values in using print_r method.
this two are same
both are the same, but array_push makes a loop in it's parameter which is an array and perform $array[]=$element
Thought I'd add to the discussion since I believe there exists a crucial difference between the two when working with indexed arrays that people should be aware of.
Say you are dynamically creating a multi-dimensional associative array by looping through some data sets.
$foo = []
foreach ($fooData as $fooKey => $fooValue) {
foreach ($fooValue ?? [] as $barKey => $barValue) {
// Approach 1: results in Error 500
array_push($foo[$fooKey], $barKey); // Error 500: Argument #1 ($array) must be of type array
// NOTE: ($foo[$fooKey] ?? []) argument won't work since only variables can be passed by reference
// Approach 2: fix problem by instantiating array beforehand if it didn't exist
$foo[$fooKey] ??= [];
array_push($foo[$fooKey], $barKey);
// Approach 3: One liner approach
$foo[$fooKey][] = $barKey; // Instantiates array if it doesn't exist
}
}
Without having $foo[$fooKey] instantiated as an array beforehand, we won't be able to do array_push without getting the Error 500. The shorthand $foo[$fooKey][] does the heavy work for us, checking if the provided element is an array, and if it isn't, it creates it and pushes the item in for us.
I know this is an old answer but it might be helpful for others to know that another difference between the two is that if you have to add more than 2/3 values per loop to an array it's faster to use:
for($i = 0; $i < 10; $i++){
array_push($arr, $i, $i*2, $i*3, $i*4, ...)
}
instead of:
for($i = 0; $i < 10; $i++){
$arr[] = $i;
$arr[] = $i*2;
$arr[] = $i*3;
$arr[] = $i*4;
...
}
edit- Forgot to close the bracket for the for conditional
No one said, but array_push only pushes a element to the END OF THE ARRAY, where $array[index] can insert a value at any given index. Big difference.
This is supposed to take any rows where ing_name is duplicated, combine the eff_name fields and delete the duplicate but it also has the side effect of changing the array from numeric to associative. My ajax is expecting numeric array.
for($i=count($recipe)-1; $i>0; $i--) {
if($recipe[$i]['ing_name'] == $recipe[$i-1]['ing_name']) { //check for duplicate. **array must be sorted by ing_name**
$recipe[$i-1]['eff_name'] .= ', '.$recipe[$i]['eff_name']; //Combine eff_name of duplicates
$recipe[$i-1]['link'] = true;
unset($recipe[$i]); //remove duplicate index
}
}
examples: NUM, ASSOC
Source
EDIT: So i figured it must have something to do with unsetting the index so I did this and it seems to work ok:
$newRecipe = array();
foreach($recipe as $r) {
$newRecipe[] = $r;
}
New question, is there a better way?
unset works with named keys. You could use array_splice instead, or get a brand new array after the loop with array_values (but that would be ugly!).
array_values() Will return a numerically indexed array