Refactoring create_function for php 7.2 - php

I need to refactor a piece of php code to work with 7.2 but i am not sure if the way i did it is correct. I could use some info about it.
This is the old code
private function sortByFields($field, &$array)
{
usort($array, create_function('$a, $b', '
$a = $a["' . $field . '"];
$b = $b["' . $field . '"];
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
'));
return true;
}
And this is the code i refactored for 7.2
private function sortByFields($field, &$array)
{
usort($array, function ($a,$b) {
$a = $a["' . $field . '"];
$b = $b["' . $field . '"];
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
});
return true;
}
Is it correct or did i mess up ?

You missed out on the "use" part so the function body does not know about the $field and messed up the $field array keys - see below:
private function sortByFields($field, &$array)
{
usort($array, function ($a,$b) use ($field) {
$a = $a[$field];
$b = $b[$field];
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
});
return true;
}

Related

whice value get in a callback function in usort() in php?

function so($a, $b) {
if($a == $b) {
return 0;
}
else {
return $a > $b ? 1 : -1;
}
}
$num = [5,3,2,1,4];
usort($num, 'so');
foreach($num as $value) {
echo $value." ";
}
I write this code and the result is 1,2,3,4,5 and it is good! But I don't understand how this usort function actually work. I even don't understand what value $a and $b get to return 0, 1 or -1 can anyone explain me it?
Print your result in so() function then you got your answer.
when usort() called it compare values with each other and return response in the form of integers 0, 1 and -1.
On the basis of that result sorting take place
function so($a, $b) {
if($a == $b) {
echo $value = 0;
return $value;
}
else {
$value = $a > $b ? 1 : -1;
echo $value;
return $value;
}
}
$num = [5,3,2,1,4];
usort($num, 'so');
foreach($num as $value) {
echo $value." ";
}

custom array sort to force certain values to start or end of array

Say I have an array
$ar = ['apples','blueberries','end','pears','dragonfruit','oranges','start','durian','lychee','rambutan','pineapple','end','start'];
I want the array in some order (lets say alphabetic order for this argument), but with the values 'end' on the tail and 'start' on the head of the array.
function cmp($a,$b) {
if ($a == $b) return 0;
if ($b === 'start') return 1;
if ($b === 'end') return -1;
return ($a < $b) ? -1 : 1;
}
usort($ar,"cmp");
echo implode(", ", $ar);
How do I sort so that values matching a specific value will end up at the head or tail of the array, but other values will sort based on other criteria (e.g. numeric, alpha, etc)
You can use array_diff with sort, array_push and array_unshift
$elements = ['start','end'];//start & end elements array
$rest = array_diff($ar, $elements);
sort($rest);//Sorting of the rest items
array_push($rest, $elements[1]);//Push end element
array_unshift($rest, $elements[0]);//Push start element
You can use rsort($rest) for descending order.
Live Example : https://3v4l.org/GnotC
Try this
$ar = ['apples','blueberries','end','pears','dragonfruit','oranges','start','durian','lychee','rambutan','pineapple','end','start', 'end', 'banana', 'yellow'];
function cmp($a, $b) {
if ($a === $b) {
return 0;
}
if ($a === 'start' || $b === 'end' ) {
return -1;
}
if( $b === 'start' || $a === 'end') {
return 1;
}
return ($a < $b) ? -1 : 1; }
usort($ar,"cmp");
echo implode(', ', $ar);
Hope this will help you
Following is how your cmp function should be. Just a couple of if statements introduced.
function cmp($a, $b) {
if ($a === $b) {
return 0;
}
if ($a === 'start' ) {
return -1;
}
if( $b === 'start' ) {
return 1;
}
if ($a === 'end' ) {
return 1;
}
if ($b === 'end' ) {
return -1;
}
return ($a < $b) ? -1 : 1;
}

Accessing a variable from a function inside a function?

I have the following code:
function create_sort_callback($criteria)
{
return function($a, $b)
{
$a = $a[$criteria];
$b = $b[$criteria];
return ($a == $b ? 0 : (($a < $b) ? -1 : 1));
};
}
It turns out I can't access $criteria from within the inner function. How can I solve this problem?
Try like this
function create_sort_callback($criteria)
{
return function($a, $b) use($criteria)
{
$a = $a[$criteria];
$b = $b[$criteria];
return ($a == $b ? 0 : (($a < $b) ? -1 : 1));
};
}
You need using closures http://www.php.net/manual/en/functions.anonymous.php
Use the use keyword.
function create_sort_callback($criteria)
{
return function($a, $b) use ($criteria)
{
$a = $a[$criteria];
$b = $b[$criteria];
return ($a == $b ? 0 : (($a < $b) ? -1 : 1));
};
}

dynamic associative array?

I have array returned
$header_html = array(1=>array('width'=>40,
'sort_case'=>23,
'title'=>'AxA'),
2=>array('width'=>50,
'sort_case'=>7,
'title'=>'B2B'),
3=>array('width'=>100,
'sort_case'=>12,
'title'=>'C12')
);
I want to get new array that depend on $header_array=array('AxA','B2B','C12')
for examples:
if have $header_array=array('C12','B2B','AxA').
the new $header_html will be:
$header_html = array(
1=>array('width'=>100,
'sort_case'=>12,
'title'=>'C12'),
2=>array('width'=>50,
'sort_case'=>7,
'title'=>'B2B'),
3=>array('width'=>40,
'sort_case'=>23,
'title'=>'AxA')
);
and so on...
Anybody know how to do this?
You can sort the array with a custom comparison function using usort:
function cmp($a, $b) {
// Sort via $a['title'] and $b['title']
}
usort($header_html, 'cmp');
The trick is coming up with a comparison function that does what you want. To simply sort backwards by title, you could use:
function cmp($a, $b) {
if ($a['title'] == $b['title'])
return 0;
// usually return -1 if $a < $b, but we're sorting backwards
return ($a['title'] < $b['title'] ? 1 : -1;
}
In PHP 5.3, you can easily do this with a functor and usort.
class MyComparator {
protected $order = array();
public function __construct() {
$values = func_get_args();
$i = 0;
foreach($values as $v) {
$this->order[$v] = $i;
$i++;
}
}
public function __invoke($a, $b) {
$vala = isset($this->order[$a['title']]) ?
$this->order[$a['title']] : count($this->order);
$valb = isset($this->order[$b['title']]) ?
$this->order[$b['title']] : count($this->order);
if($vala == $valb) return 0;
return $vala < $valb ? -1 : 1;
}
}
You can use it like that:
$sorter = new MyComparator('CCC', 'AAA', 'BBB');
usort($header_html, $sorter);
You need a user-defined sort so you can access individual fields of the elements to sort:
function mysort($a, $b)
{
global $header_array;
$pos1 = array_search($a["title"], $header_array);
$pos2 = array_search($b["title"], $header_array);
if ($pos1 == $pos2) { return 0; }
return $pos1 < $pos2 ? -1 : 1;
}
$header_array = array("CCC", "BBB", "AAA");
usort($header_html, "mysort");
print_r($header_array);
note: usort() returns true on success or false on failure; it does not return the resorted array.
It sounds like you want a function to return the array elements in the order you specify in $header_array. If so, here's a stab:
function header_resort($header_array, $header_html) {
foreach($header_array as $i => $val) {
foreach($header_html as $obj) {
if( $obj->title == $val )
$header_html_new[$i] = $obj;
}
}
return $header_html_new;
}

usort - more parameters

Hallo, how can I pass more parameters to usort?
I have different functions, which are very similar in structure, I want to have just one function:
<?php
$arr = array( array('number' => 100, 'string'=>'aaa'),
array('number'=>50, 'string'=>'bdef'),
array('number'=>150, 'string'=>'cbba')
);
usort($arr, 'sortNumberDesc');
//How can I use just a single function?
//How can I pass further parameters to usort?
function sortNumberDesc($a, $b){
$a = $a['number'];
$b = $b['number'];
if ($a == $b) return 0;
return ($a > $b) ? -1 : +1;
}
function sortNumberAsc($a, $b){
$a = $a['number'];
$b = $b['number'];
if ($a == $b) return 0;
return ($a < $b) ? -1 : +1;
}
//I want to do the same with just one function:
//Sort ID is the search index, reverse DESC or ASC
function sort($a, $b, $sortId='number', $reverse = 0){
$a = $a[$sortId];
$b = $b[$sortId];
if ($a == $b) return 0;
if($reverse == false) return ($a > $b) ? -1 : +1;
else return ($a < $b) ? -1 : +1;
}
print_r($arr);
?>
You can use a much simpler function:
function sortNumberAsc($a, $ b){
$a = $a['number'];
$b = $ b['number'];
if ($a == $b) return 0;
return ($a < $b) ? -1 : +1;
}

Categories