I want to get all rows (in descending order) which have a "score" in the top five of all scores. Because there may be ties, it is possible that there will be more than 5 rows in the result array.
I have an array in PHP :
Array
(
[0] => Array([number] => 1162)
[1] => Array([number] => 1162)
[2] => Array([number] => 1158)
[3] => Array([number] => 1157)
[4] => Array([number] => 1157)
[5] => Array([number] => 1130)
[6] => Array([number] => 1117)
[7] => Array([number] => 1097)
[8] => Array([number] => 1086)
)
I want the rows with the top 5 ranks. The final output contains 7 rows because of ties:
Array
(
[0] => Array([number] => 1162) #1 Rank
[1] => Array([number] => 1162) #1 Rank
[2] => Array([number] => 1158) #2 Rank
[3] => Array([number] => 1157) #3 Rank
[4] => Array([number] => 1157) #3 Rank
[5] => Array([number] => 1130) #4 Rank
[6] => Array([number] => 1117) #5 Rank
)
How can I achieve this? This array value data can be changed according to the situation.
You first need to order the array Desc. Adjust how much ranking you want using the variable $limit.
<?php
$limit = 5;
$arr = array();
$arr[] = array('number' => 1162);
$arr[] = array('number' => 1162);
$arr[] = array('number' => 1158);
$arr[] = array('number' => 1157);
$arr[] = array('number' => 1157);
$arr[] = array('number' => 1130);
$arr[] = array('number' => 1117);
$arr[] = array('number' => 1097);
$arr[] = array('number' => 1086);
function sortByOrder($a, $b) {
return $b['number'] - $a['number'];
}
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['number'] === $id) {
return true;
}
}
return false;
}
usort($arr, 'sortByOrder');
$new_arr = array();
$i = 0;
foreach($arr as $key => $value){
$checkDuplicate = searchForId($value['number'], $new_arr);
if(!$checkDuplicate){
$i++;
}
if($i > $limit){
break;
}
$new_arr[] = $value;
}
var_dump($new_arr);
Result:
array(7) {
[0]=>
array(1) {
["number"]=>
int(1162)
}
[1]=>
array(1) {
["number"]=>
int(1162)
}
[2]=>
array(1) {
["number"]=>
int(1158)
}
[3]=>
array(1) {
["number"]=>
int(1157)
}
[4]=>
array(1) {
["number"]=>
int(1157)
}
[5]=>
array(1) {
["number"]=>
int(1130)
}
[6]=>
array(1) {
["number"]=>
int(1117)
}
}
Demo: https://sandbox.onlinephpfunctions.com/c/49751
Because you array of rows are consistently formatted, you can simply call rsort() to natively sort the data in a descending fashion.
Next iterate the sorted array and maintain an incremented "counter" variable ($rank) -- only increase this value when a new $number is encountered. So long as the rank of the current number is less than on equal to the $maxRank, push the $number into the result array. In other words, when the current rank exceeds the max rank, do not push any more numbers into the result and stop iterating.
Code: (Demo)
$array = [
['number' => 1117],
['number' => 1097],
['number' => 1162],
['number' => 1158],
['number' => 1162],
['number' => 1157],
['number' => 1086],
['number' => 1157],
['number' => 1130],
];
$maxRank = 5;
rsort($array); // sort DESC
$rank = 0;
$result = [];
foreach ($array as ['number' => $number]) {
$ranks[$number] ??= ++$rank;
if ($ranks[$number] > $maxRank) {
break;
}
$result[] = $number;
}
var_export($result);
Output:
array (
0 => 1162,
1 => 1162,
2 => 1158,
3 => 1157,
4 => 1157,
5 => 1130,
6 => 1117,
)
To see how the ranks are distributed without the break, see this demo.
Related
In PHP we do have function array_flip for exchanging all keys with their associated values in an array, however I am looking for a the solution as follows with the help of php functions
INPUT
array(
"a" => 1,
"b" => 1,
"c" => 2
);
OUTPUT
array(
1 => array("a", "b"),
2 => "c"
);
I don't think there is a php function for it, so you'll have to write your own. If you really want a mixture of nested arrays and values the way to go would be:
function my_array_flip($arr)
{
$new_arr = array();
foreach ($arr as $k => $v)
{
if (array_key_exists($v, $new_arr))
{
if (is_array($new_arr[$v]))
{
$new_arr[] = $k;
}
else
{
$new_arr[$v] = array($new_arr[$v]);
$new_arr[$v][] = $k;
}
}
else
{
$new_arr[$v] = $k;
}
}
return $new_arr;
}
For your array this will return:
Array
(
[1] => Array
(
[0] => a
[1] => b
)
[2] => c
)
$source = array(
"a" => 1,
"b" => 1,
"c" => 2
);
foreach ($source as $key => $value)
{
$result[$value][] = $key;
}
Don't think exists a function for that but you can achieve it with some code:
$input = [
"a" => 1,
"b" => 1,
"c" => 2,
];
$grouped = [];
foreach ($input as $key => $group) {
$grouped[$group][] = $key;
}
Result:
var_dump($grouped);
array(2) {
[1] =>
array(2) {
[0] =>
string(1) "a"
[1] =>
string(1) "b"
}
[2] =>
array(1) {
[0] =>
string(1) "c"
}
}
Sets always array as values because I guess this will simplify things when you'll use the result in your code.
i've got this array (from a csv file) :
array (
0 => 'entity_id;commission_book;old_price;new_price',
1 => '667;667;667;667',
2 => '668;668;668;668'
)
How to build a new array that looks like :
[0] : (
'entity_id' => '667',
'commission_book' => '667',
'old_price' => '667',
'new_price' => '667',
);
[1] : (
'entity_id' => '668',
'commission_book' => '668',
'old_price' => '668',
'new_price' => '668',
)
In other words, i want to buid 2 objects using the first array, is there any way to perfom that please ? I'm trying for hours now
This is a simply but elegant way to do that:
<?php
$input = [
0 => 'entity_id;commission_book;old_price;new_price',
1 => '667;667;667;667',
2 => '668;668;668;668'
];
$output = [];
// drop header entry
array_shift($input);
// process remaining entries
foreach ($input as $key=>$entry) {
$x = &$output[$key];
list(
$x['entity_id'],
$x['commission_book'],
$x['old_price'],
$x['new_price']
) = explode(';', $entry);
}
print_r($output);
The output of the above is:
Array
(
[0] => Array
(
[new_price] => 667
[old_price] => 667
[commission_book] => 667
[entity_id] => 667
)
[1] => Array
(
[new_price] => 668
[old_price] => 668
[commission_book] => 668
[entity_id] => 668
)
)
Short solution with array_slice and array_combine:
$from_csv = [
0 => 'entity_id;commission_book;old_price;new_price',
1 => '667;667;667;667',
2 => '668;668;668;668'
];
$result = [];
$keys = explode(";", $from_csv[0]); // header fields
foreach(array_slice($from_csv, 1) as $v){
$result[] = array_combine($keys, explode(";", $v));
}
echo '<pre>';
var_dump($result);
// the output:
array(2) {
[0]=>
array(4) {
["entity_id"]=>
string(3) "667"
["commission_book"]=>
string(3) "667"
["old_price"]=>
string(3) "667"
["new_price"]=>
string(3) "667"
}
[1]=>
array(4) {
["entity_id"]=>
string(3) "668"
["commission_book"]=>
string(3) "668"
["old_price"]=>
string(3) "668"
["new_price"]=>
string(3) "668"
}
}
$array = array(
0 => 'entity_id;commission_book;old_price;new_price',
1 => '667;667;667;667',
2 => '668;668;668;668');
$array[0] = explode(";",$array[0]);
$array[1] = explode(";",$array[1]);
$array[2] = explode(";",$array[2]);
$newarray = array();
for ($i=0;$i<count($array[0]);$i++){
$newarray[0][$array[0][$i]] = $array[1][$i];
$newarray[1][$array[0][$i]] = $array[2][$i];
}
echo "<pre>";
var_dump($array);
var_dump($newarray);
echo "</pre>";
I am trying to update each language as a multidimensional array to another multidimensional array but it seems to be only saving the last key e.g.(lang_3) but not lang_1 & lang_2. Cracking my head to figure this out. Hope someone can point out my faults. ($country_specs = list of language, $get_code = country code)
$awards = array(
'award_year' => sanitize_array_text_field($_POST['award_year']),
'award_title_user' => sanitize_array_text_field($_POST['award_title_user']),
'award_description_user' => sanitize_array_text_field($_POST['award_description_user'])
);
foreach ($country_specs as $specs => $value) {
if ($value[0] == $get_code ) {
foreach ($value['lang'] as $lang_key => $lang) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_lang = array(
$awards_title => sanitize_array_text_field($_POST[$awards_title]),
$awards_description => sanitize_array_text_field($_POST[$awards_description])
);
update_user_meta($user_id, 'awards', array_merge($awards,$awards_lang));
}
}
}
Current code output example:
Array (
[award_year] => Array (
[0] => 1999-01
[1] => 2010-02 )
[award_title_user] => Array (
[0] => 2
[1] => tt )
[award_description_user] => Array (
[0] => 2
[1] => ddd )
[award_title_lang3] => Array (
[0] => 2CC
[1] => zz )
[award_description_lang3] => Array (
[0] => 2CCCCCCC
[1] => dzz ) )
Working code as follows.
$awards = array(
'award_year' => sanitize_array_text_field($_POST['award_year']),
'award_title_user' => sanitize_array_text_field($_POST['award_title_user']),
'award_description_user' => sanitize_array_text_field($_POST['award_description_user'])
);
$awards_new_lang = array();
foreach ($country_specs as $specs => $value) {
if ($value[0] == $get_code ) {
foreach ($value['lang'] as $lang_key => $lang) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_new_lang[$awards_title] = sanitize_array_text_field($_POST[$awards_title]);
$awards_new_lang[$awards_description] = sanitize_array_text_field($_POST[$awards_description]);
}
}
}
$array_merge_new = array_merge($awards, $awards_new_lang);
update_user_meta($user_id, 'awards', $array_merge_new);
I created a new array ($awards_new_lang) and did an array merge with the old array, thus combining both of the arrays together.
Try this code, it outputs as expected, I tried the mimic the variables structures
<?php
$awards = array(
'award_year' => '1999',
'award_title_user' => '2',
'award_description_user' => '2CCCCCCC'
);
$value = array();
$value['lang'] = array(1, 2, 3);
foreach ($value['lang'] as $lang_key) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_lang = array(
$awards_title => "$lang_key title",
$awards_description => "$lang_key desc"
);
//array merge returns an array, we save the changes here to use them later when the loops are through
$awards = array_merge($awards,$awards_lang);
}
echo '<pre>';
//Final updated version of the array
var_dump($awards);
echo '</pre>';
?>
Outputs:
array(9) {
["award_year"]=>
string(4) "1999"
["award_title_user"]=>
string(1) "2"
["award_description_user"]=>
string(8) "2CCCCCCC"
["award_title_1"]=>
string(7) "1 title"
["award_description_1"]=>
string(6) "1 desc"
["award_title_2"]=>
string(7) "2 title"
["award_description_2"]=>
string(6) "2 desc"
["award_title_3"]=>
string(7) "3 title"
["award_description_3"]=>
string(6) "3 desc"
}
This is my array :
Array
(
[0] => Array
(
[0] => S No.
[1] => Contact Message
[2] => Name
[3] => Contact Number
[4] => Email ID
)
[1] => Array
(
[0] => 1
[1] => I am interested in your property. Please get in touch with me.
[2] => lopa <br/>(Individual)
[3] => 1234567890
[4] => loperea.ray#Gmail.com
)
[2] => Array
(
[0] => 2
[1] => This user is looking for 3 BHK Multistorey Apartment for Sale in Sohna, Gurgaon and has viewed your contact details.
[2] => shiva <br/>(Individual)
[3] => 2135467890
[4] => sauron82#yahoo.co.in
)
)
How can I retrieve all data element wise?
You can get information about arrays in PHP on the official PHP doc page
You can access arrays using square braces surrounding the key you like to select [key].
So $array[1] will give yoo:
Array
(
[0] => 1
[1] => I am interested in your property. Please get in touch with me.
[2] => lopa <br/>(Individual)
[3] => 1234567890
[4] => loperea.ray#Gmail.com
)
And $array[1][2] will give you:
lopa <br/>(Individual)
Or you can walkt through the elements of an array using loops like the foreach or the for loop.
// perfect for assoc arrays
foreach($array as $key => $element) {
var_dump($key, $element);
}
// alternative for arrays with seamless numeric keys
$elementsCount = count($array);
for($i = 0; $i < $elementsCount; ++$i) {
var_dump($array[$i]);
}
You have integer indexed elements in multidimensional array. To access single element from array, use array name and it's index $myArray[1]. To get inner element of that previous selected array, use second set of [index] - $myArray[1][5] and so on.
To dynamically get all elements from array, use nested foreach loop:
foreach ($myArray as $key => $values) {
foreach ($values as $innerKey => $value) {
echo $value;
// OR
echo $myArray[$key][$innerKey];
}
}
The solution is to use array_reduce:
$header = array_map(
function() { return []; },
array_flip( array_shift( $array ) )
); // headers
array_reduce( $array , function ($carry, $item) {
$i = 0;
foreach( $carry as $k => $v ) {
$carry[$k][] = $item[$i++];
}
return $carry;
}, $header );
First of all we get the header from the very first element of input array. Then we map-reduce the input.
That gives:
$array = [['A', 'B', 'C'], ['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3']];
/*
array(3) {
'A' =>
array(3) {
[0] =>
string(2) "a1"
[1] =>
string(2) "a2"
[2] =>
string(2) "a3"
}
'B' =>
array(3) {
[0] =>
string(2) "b1"
[1] =>
string(2) "b2"
[2] =>
string(2) "b3"
}
'C' =>
array(3) {
[0] =>
string(2) "c1"
[1] =>
string(2) "c2"
[2] =>
string(2) "c3"
}
}
*/
I think this is what you are looking for
$array = Array
(
0=> Array
(
0 => 'S No.',
1 => 'Contact Message',
2 => 'Name',
3 => 'Contact Number',
4 => 'Email ID'
),
1 => Array
(
0 => 1,
1 => 'I am interested in your property. Please get in touch with me.',
2 => 'lopa <br/>(Individual)',
3 => '1234567890',
4 => 'loperea.ray#Gmail.com',
),
2 => Array
(
0 => 2,
1 => 'This user is looking for 3 BHK Multistorey Apartment for Sale in Sohna, Gurgaon and has viewed your contact details.',
2 => 'shiva <br/>(Individual)',
3 => '2135467890',
4 => 'sauron82#yahoo.co.in',
)
);
$result_array = array();
array_shift($array);
reset($array);
foreach($array as $x=>$array2){
foreach($array2 as $i => $arr){
if($i == 1){
$result_array[$x]['Contact Message'] = $arr;
}elseif($i == 2){
$result_array[$x]['Name'] = $arr;
}elseif($i == 3){
$result_array[$x]['Contact Number'] =$arr;
}elseif($i == 4){
$result_array[$x]['Email ID'] = $arr;
}
}
}
print_r($result_array);
I am trying to search a multi-dimensional associative array and change a value after searching. Here is what my array looks like
$arr=Array ( [0] => Array ( [1] =>
Array ( [keyword] => 2014
[count] => 97
[percent] => 4.91 )))
So what I am trying to do is to search for keyword and if found then increase the count on that particular index where keyword was found.
So I am trying to do something like:
if(in_array("2014", $arr))
{
//then add 100 to count that is 100+97
}
So what will be the best way to go about this.
Note: I am trying to search a value in the array and if found then update the value of count key on that particular index. The last part is as important as first.
Ahmar
you can use that code:
$arr = Array(
0 => Array(
1 => Array(
'keyword' => 2014,
'count' => 97,
'percent' => 4.91
)
)
);
foreach ($arr as &$arr1) {
foreach ($arr1 as &$arr2) {
if (2014 == $arr2['keyword']) {
$arr2['count'] += 100;
}
}
}
unset($arr2, $arr1);
Result:
array(1) {
[0]=>
array(1) {
[1]=>
array(3) {
["keyword"]=>
int(2014)
["count"]=>
int(197)
["percent"]=>
float(4.91)
}
}
}
iterate through the dimensions of the array and change value if you found the key
foreach ($arr as $key => $val) {
foreach ($arr[$key] as $keyy => $val) {
foreach ($arr[$key][$keyy] as $keyyy => $val) {
if($arr[$key][$keyy]['keyword'] == 2014){
$arr[$key][$keyy]['count'] = $arr[$key][$keyy]['count']+100;
break;
}
}
}
}
hope it helps ;D
Your array
$arr=array( "0" => array( "1" =>
array( "keyword" => 2014 ,
"count" => 97,
"percent" => 4.91 ),
"2"=> array( "keyword" => 2015,
"count" => 5,
"percent" => 4.91 )));
Code
foreach($arr as $key => &$val) {
foreach($val as $mm => &$aa) {
if("2014" == $aa['keyword']) {
$aa["count"] = $aa["count"]+ 100;
}
}
}
print_r($arr);
Sandbox url: http://sandbox.onlinephpfunctions.com/code/fc2fd3a5bd3593c88efdb50c4a57b0812a7512c9