Get the highest values from an array - php

I have an array stored in a variable $data. The array has names in the first row and a value in the second row. The array is very big so I need a way to take the five highest values from it and the name from those value. For example I have this array:
[0]=>
array(1447) {
[1]=>
array(3) {
[0]=>
string(11) "Cris"
[2]=>
string(1) "11"
}
[2]=>
array(3) {
[0]=>
string(7) "Alan"
[2]=>
string(1) "28"
}
[3]=>
array(3) {
[0]=>
string(6) "Alex"
[2]=>
string(1) "50"
}
[4]=>
array(3) {
[0]=>
string(6) "Zone"
[1]=>
string(1) "22"
}
[5]=>
array(3) {
[0]=>
string(6) "Ana"
[2]=>
string(1) "1"
}
[6]=>
array(3) {
[0]=>
string(6) "Fisca"
[1]=>
string(1) "5"
}
In this case I should display: Alex 50, Alan 28, Zone 22, Cris 11 and Fisca 5. I tried to find a solution but I don't know how should I make a top of array values. Can you help me please? Thank you in advance.

First sort your array and then slice the top 5:
DEMO
usort($data, function ($a, $b) {
return $b[1] - $a[1];
}); //Sort your array
$resultant = array_slice($data,0,5); //Pick top 5
Note: If your index used for comparison differs, then change your return statement to:
return (isset($b[1])?$b[1]:$b[2]) - (isset($a[1])?$a[1]:$a[2]);
Example:
<?php
$data = [
['Cris', 11],
['Alan', 28],
['Alex', 50],
['Zone', 22],
['Ana', 1]
];
usort($data, function ($a, $b) {
return $b[1] - $a[1];
});
print_r(array_slice($data,0,5));
Result:
Array
(
[0] => Array
(
[0] => Alex
[1] => 50
)
[1] => Array
(
[0] => Alan
[1] => 28
)
[2] => Array
(
[0] => Zone
[1] => 22
)
[3] => Array
(
[0] => Cris
[1] => 11
)
[4] => Array
(
[0] => Ana
[1] => 1
)
)
DEMO

You can use this to get the 5 highest values of your array:
<?php
function compare($a, $b) {
if ($a[1] == $b[1]) {
return 0;
}
return ($a[1] > $b[1]) ? -1 : 1;
}
usort($theBigArray, "compare");
$fiveHighestValues = array_slice($theBigArray, 0, 5);
?>
($theBigArray being your array)
And then, you can loop through the $fiveHighestValues var to display the five elements as you want, e.g.:
<?php
foreach($fiveHighestValues as $value) {
echo $value[0] .' has the value '. $value[1];
// output: Alex has the value 50
}
?>

I would first sort the array like this
function mySort($a, $b) {
return $b[1] - $a[1];
}
usort($arr, 'mySort');
Then you can just pop the first 5 values - they are the highest.
You've written that 'The array has names in the first row and a value in the second row.', but I can see that for 'Zone' the index '1' is set not '2', so in your sorting function you might need to add some simple checking, maybe something like this:
function mySortWithCheck($a, $b) {
if (isset($b[1])) {
$valB = $b[1];
} else {
$valB = $b[2];
}
if (isset($a[1])) {
$valA = $a[1];
} else {
$valA = $a[2];
}
return $valB - $valA;
}

<?php
$data = array(
array("Cris", "11"),
array("Alan", "28"),
array("Alex","50"),
array("Zone","22"),
array("Ana","1")
);
var_dump($data);
function custom_array_sort($a, $b) {
return $b[1] - $a[1];
}
usort($data,'custom_array_sort');
$sorted = array_slice($data,0,5);
var_dump($sorted);
?>

Related

Create new Array under same key from multiple Array in PHP [duplicate]

This question already has answers here:
Transpose 2d array, join second level with commas, and join first level with pipes
(5 answers)
Closed 7 months ago.
I have the following array.
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/02/2019");
$c = array("08/01/2020", "08/02/2019");
print_r($a);
print_r($b);
print_r($b);
and the output is
Array(
[0] => Algebra
[1] => Arithmetic
)
Array(
[0] => 08/01/2020
[1] => 08/01/2019
)
Array(
[0] => 08/02/2020
[1] => 08/02/2019
)
And I want Array in the following structure.
Array(
[0] => Algebra,08/01/2020,08/02/2020
[1] => Arithmetic,08/01/2019,08/02/2019
)
I have tried $results = array_merge_recursive($a, $b, $c); but its not giving desire output.
Thanks for help in advance.
A simple foreach loop will suffice
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/02/2019");
$c = array("08/01/2020", "08/02/2019");
foreach( $a as $i=>$v ) {
$new[] = sprintf( '%s,%s,%s', $v, $b[$i], $c[$i] );
}
Firstly, when you find yourself using sequentially-named variables it almost always means that they should actually be an array:
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/02/2019");
$c = array("08/01/2020", "08/02/2019");
$better_array = [$a, $b, $c];
var_dump($better_array);
Output:
array(3) {
[0]=>
array(2) {
[0]=>
string(7) "Algebra"
[1]=>
string(10) "Arithmetic"
}
[1]=>
array(2) {
[0]=>
string(10) "08/01/2020"
[1]=>
string(10) "08/02/2019"
}
[2]=>
array(2) {
[0]=>
string(10) "08/01/2020"
[1]=>
string(10) "08/02/2019"
}
}
Once they're in an proper array you can use array_column()
$out = [];
for($i=0, $c=count($better_array[0]); $i < $c; ++$i) {
$out[] = array_column($better_array, $i);
}
var_dump($out);
Output:
array(2) {
[0]=>
array(3) {
[0]=>
string(7) "Algebra"
[1]=>
string(10) "08/01/2020"
[2]=>
string(10) "08/01/2020"
}
[1]=>
array(3) {
[0]=>
string(10) "Arithmetic"
[1]=>
string(10) "08/02/2019"
[2]=>
string(10) "08/02/2019"
}
}
And if that comma-delimited string is what you actually want, then use implode():
$out = [];
for($i=0, $c=count($better_array[0]); $i < $c; ++$i) {
$out[] = implode(',', array_column($better_array, $i));
}
var_dump($out);
Output:
array(2) {
[0]=>
string(29) "Algebra,08/01/2020,08/01/2020"
[1]=>
string(32) "Arithmetic,08/02/2019,08/02/2019"
}
Lastly, you should avoid print_r() as it tends to produce misleading output. Eg: https://3v4l.org/ThSLb
You don't get anything built-in for this purpose. You need to build a custom function for this. You can try this-
<?php
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/01/2019");
$c = array("08/02/2020", "08/02/2019");
function mergeAssoc()
{
// You can get variable number of arguments|array by this.
$args = func_get_args();
$master = array();
foreach ($args as $arg)
{
foreach ($arg as $i => $v)
{
$master[$i][] = $v;
}
}
return $master;
}
$res = mergeAssoc($a, $b, $c);
print_r($res);
Note: It will return a multidimensional array. Not an array of comma-separated values.
Output:
Array
(
[0] => Array
(
[0] => Algebra
[1] => 08/01/2020
[2] => 08/02/2020
)
[1] => Array
(
[0] => Arithmetic
[1] => 08/01/2019
[2] => 08/02/2019
)
)
and if we use foreach then our desire output will be there with array separated by comma.
foreach ($res as $key => $value) {
$result[] = implode(',', $value);
}
and output of print_r($result); is
Array
(
[0] => Algebra,08/01/2020,08/02/2020
[1] => Arithmetic,08/01/2019,08/02/2019
)

Combine multiple arrays with identica keys and different values

I have this two arrays that are generated in two foreach loops and I want to set the first array as keys and the second one as values.
after I use this code
foreach ($difference AS $j) {
$fv = $cate->getFilterValueByFeatureID($j);
foreach ($fv AS $z) {
$array = array(
$j => $z
);
var_dump($array);
}
}
this is what I get
array(1) {
[6]=>
int(15)
}
array(1) {
[6]=>
int(20)
}
array(1) {
[8]=>
int(26)
}
array(1) {
[8]=>
int(27)
}
array(1) {
[8]=>
int(33)
}
and I want this result
array(1){
[6] => array(
[0] => 15
[1] => 20
)
array(1){
[8] => array(
[0] => 26
[1] => 27
[2] => 33
)
Like this (untested)
$result = [];
foreach ($difference AS $j) {
$fv = $cate->getFilterValueByFeatureID($j);
foreach ($fv AS $z) {
if(!isset($result[$j])) $result[$j] = [];
$result[$j][] = $z;
}
}
var_dump($result);

How to update data if array is empty?

I want to update empty array .So I check is empty and want to update the original variable.So I tried by & but it doesn't change empty array $array2 .I had tried many hours but not working!!!
<?php
$array1 = array('one','two','three');
$array2 = array();
$array3 = array ('four');
$array4 = array ('five','six');
check([&$array1,&$array2,&$array3,&$array4]);
function check($arr){
foreach ($arr as $k=>$value) {
if(empty($value)){
$arr[$k][] = "nothing";
return $arr[$k];
}
else{
return $arr[$k];
}
}
}
var_dump($array2);
//actual output : empty
//expect output : 0 => string 'nothing'
?>
Have a look following code.
$array1 = array('one','two','three');
$array2 = array();
$array3 = array ('four');
$array4 = array ('five','six');
$arr11=check([&$array1,&$array2,&$array3,&$array4]);
function check($arr){
foreach ($arr as $k=>$value) {
print_r($value);
if(empty($value)){
$arr[$k] = "nothing";
}
else{
$arr[$k];
}
}
return $arr;
}
print_r($arr11);
var_dump($array2);
//actual output : empty
//expect output : 0 => string 'nothing'
It will display following result.
Array
(
[0] => Array
(
[0] => one
[1] => two
[2] => three
)
[1] => nothing
[2] => Array
(
[0] => four
)
[3] => Array
(
[0] => five
[1] => six
)
)
string(7) "nothing"
This will work for you:
<?php
$array1 = array('one','two','three');
$array2 = array();
$array3 = array ('four');
$array4 = array ('five','six');
list($array1, $array2, $array3, $array4) = check([$array1,$array2,$array3,$array4]);
function check($arr){
foreach ($arr as $k => $value) {
if(empty($value)){
$arr[$k] = "nothing";
}
}
return $arr;
}
var_dump($array2);
//actual output : string(7) "nothing"
//expect output : string(7) "nothing"
?>
You've written your function very strangely, actually.
UPDATE. Output of other arrays instead of only one.
var_dump($array1, $array2, $array3, $array4);
array(3) {
[0]=>
string(3) "one"
[1]=>
string(3) "two"
[2]=>
string(5) "three"
}
string(7) "nothing"
array(1) {
[0]=>
string(4) "four"
}
array(2) {
[0]=>
string(4) "five"
[1]=>
string(3) "six"
}

Remove array from multi-dimensional indexed array based on duplicate value [duplicate]

This question already has answers here:
PHP unique array by value?
(6 answers)
Closed 6 years ago.
I have a PHP array that looks like this,
[["a","b"],["e","j"],["a","s"]]
I need it to look like this,
[["a","b"],["e","j"]]
or this,
[["e","j"],["a","s"]]
I cannot have two inner arrays that contain the same "0" index. It does not matter which inner array is deleted as long as only one remains. How can I go through this array and remove inner arrays that contain the same "0" index?
Thanks!
You could simply loop through the array with two loops. Let's say this is your data:
$data = array(
array('a', 'b'),
array('e', 'j'),
array('a', 's'),
array('a', 't'),
array('c', 't'),
array('a', 'h'),
array('c', 'e'),
array('f', 'g')
);
Then you go ahead and loop through everything, and unset it if it's the same value.
$count = count($data);
foreach($data as $index => $array){
for($i=$index + 1; $i<$count; $i++)
if(isset($array[0]) && isset($data[$i][0]) && $array[0] == $data[$i][0])
unset($data[$i]);
}
The var_dump of $data after the loops would be:
array(4) {
[0]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
}
[1]=>
array(2) {
[0]=>
string(1) "e"
[1]=>
string(1) "j"
}
[4]=>
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "t"
}
[7]=>
array(2) {
[0]=>
string(1) "f"
[1]=>
string(1) "g"
}
}
<?php
$array = [["a","b"],["e","j"],["a","s"]];
$values = array();
foreach ($array as $key => $arrayChild) {
foreach ($arrayChild as $val) {
if (in_array($val, $values)) {
unset($array[$key]);
}
$values[] = $val;
}
}
print_r($array);
?>
Result:
Array (
[0] => Array ( [0] => a [1] => b )
[1] => Array ( [0] => e [1] => j )
)

Sort array based on the numbers and a certain piece of text that occurs within a string

I have an array which I got from a directory with pdf files in it using scandir
$array = array(7) {
[0]=> string(17) "q150824-spost.pdf"
[1]=> string(17) "s150826-spost.pdf"
[2]=> string(16) "s150826-spro.pdf"
[3]=> string(17) "t150827-spost.pdf"
[4]=> string(16) "t150827-spro.pdf"
[5]=> string(17) "v150825-spost.pdf"
[6]=> string(16) "v150825-spro.pdf"
}
I need to sort the array by the numbers in the file name (eg. 150824 which is actually a date) which I can do using the following:
usort($array, function($a, $b) {
return filter_var($a, FILTER_SANITIZE_NUMBER_INT) - filter_var($b, FILTER_SANITIZE_NUMBER_INT);
});
The above gives me an array sorted by the numbers (which is almost what I want):
$array = array(7) {
[0]=> string(17) "q150824-spost.pdf"
[1]=> string(17) "v150825-spost.pdf"
[2]=> string(16) "v150825-spro.pdf"
[3]=> string(16) "s150826-spro.pdf"
[4]=> string(17) "s150826-spost.pdf"
[5]=> string(17) "t150827-spost.pdf"
[6]=> string(16) "t150827-spro.pdf"
}
However, in addition to this I would also like to sort alphabetically by spost and spro (the text before .pdf) I'm at a loss as to how to achieve this though?
If two strings in the array have the same numbers/date (eg. 150826) I want to then sort by spost first and then spro.
This should work for you:
First just grab the number and the topic name out of the file name with preg_match_all() and assign it to the variables. After this simply sort it by the topic, if the numbers are equal, otherwise by the numbers.
<?php
usort($arr, function($a, $b){
preg_match_all("/^\w(\d+)-(\w+)/", $a, $mA);
preg_match_all("/^\w(\d+)-(\w+)/", $b, $mB);
$numberA = $mA[1][0];
$numberB = $mB[1][0];
$topicA = $mA[2][0];
$topicB = $mB[2][0];
if($numberA == $numberB){
return strcmp($topicA, $topicB);
}
return $numberA > $numberB ? 1 : -1;
});
print_r($arr);
?>
output:
Array
(
[0] => q150824-spost.pdf
[1] => v150825-spost.pdf
[2] => v150825-spro.pdf
[3] => s150826-spost.pdf
[4] => s150826-spro.pdf
[5] => t150827-spost.pdf
[6] => t150827-spro.pdf
)
Actually you can just do the following
$array =[
"q150824-spost.pdf",
"s150826-spost.pdf",
"s150826-spro.pdf",
"t150827-spost.pdf",
"t150827-spro.pdf",
"v150825-spost.pdf",
"v150825-spro.pdf",
];
usort($array, function($a, $b) {
return filter_var($a, FILTER_SANITIZE_NUMBER_INT) - filter_var($b, FILTER_SANITIZE_NUMBER_INT) + (strlen($b) > strlen($a) ? 1 : 0);
});
print_r($array);
Output
Array
(
[0] => q150824-spost.pdf
[1] => v150825-spost.pdf
[2] => v150825-spro.pdf
[3] => s150826-spost.pdf
[4] => s150826-spro.pdf
[5] => t150827-spost.pdf
[6] => t150827-spro.pdf
)
It is sort by spost first and then spro

Categories