Here is my array:
$arrayA = array(0 => "someString",
1 => "otherString",
2 => "2017",
3 => "anotherString",
4 => "2016");
My goal is to to find the first item that has a numeric value (which would be "2017") and place it first in the array, without changing its original key and keeping the others in the same order.
So I want:
$arrayA = array(2 => "2017",
0 => "someString",
1 => "otherString",
3 => "anotherString",
4 => "2016");
I tried uasort() php function and it seems the way to do it, but I could not figure out how to build the comparison function to go with it.
PHP documentation shows an example:
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
But, WHO is $a and WHO is $b?
Well, I tried
function my_sort($a,$b) {
if ($a == $b ) {
return 0;
}
if (is_numeric($a) && !is_numeric($b)) {
return -1;
break;
}
}
But, of course, I am very far from my goal. Any help would be much appreciated.
You don't need to sort per se. Once you find the element in question, you can simply push it onto the front of the array with the + operator:
foreach ($arrayA as $k => $v) {
if (is_numeric($v)) {
$arrayA = [$k => $v] + $arrayA;
break;
}
}
print_r($arrayA);
Yields:
Array
(
[2] => 2017
[0] => someString
[1] => otherString
[3] => anotherString
[4] => 2016
)
Hello how to sort arrays by keys and values too... so if user input this value
$input = array(0,1,0,2,0);
then the result should be like this since they're the same input they should maintain their keys too...
Array
(
[0] => 0
[2] => 0
[4] => 0
[1] => 1
[3] => 2
)
not like this... the keys is jumbled and I really that key to work on my project of FCFS Scheduling.
Array
(
[4] => 0
[0] => 0
[2] => 0
[1] => 1
[3] => 2
)
btw I used asort. someone help me how to fix this?
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(0,1,0,2,0);
usort($a, "cmp");
foreach ($a as $key => $value) {
echo " $value\n";
}
Stable sort would help here. But php don't have any stable sorting functions since 4.1.
But you can use uksort + closure.
$input = array(0,1,0,2,0);
$cmp = function($a, $b) use($input){
if($input[$a] > $input[$b]){return 1;}
elseif($input[$a] < $input[$b]){return -1;}
elseif($a>$b){return 1;}
elseif($a<$b){return -1;}
return 0;
};
uksort($input, $cmp);
print_r($input);
https://eval.in/145923
Or shorter version
$cmp = function($a, $b) use($input){
return (($input[$a]-$input[$b])?:($a-$b));
};
Simple use the sort function
$input = array(0,1,0,2,0);
sort($input);
Result:-
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 2
)
I need to divide an array into two arrays.
One array will contain all positive values (and zeros), the other all negative values.
Example array:
$ts = [7,-10,13,8,0,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7];
Negatives result array:
[-10,-7.2,-12,-3.7,-9.6,-1.7,-6.2];
Non-negatives result array:
[7,13,8,0,4,3.5,6.5,7];
Without using any array functions..
Pretty straightforward. Just loop through the array and check if the number is less than 0, if so , push it in the negative array else push it in the positive array.
<?php
$ts=array(7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7);
$pos_arr=array(); $neg_arr=array();
foreach($ts as $val)
{
($val<0) ? $neg_arr[]=$val : $pos_arr[]=$val;
}
print_r($pos_arr);
print_r($neg_arr);
OUTPUT :
Array
(
[0] => 7
[1] => 13
[2] => 8
[3] => 4
[4] => 3.5
[5] => 6.5
[6] => 7
)
Array
(
[0] => -10
[1] => -7.2
[2] => -12
[3] => -3.7
[4] => -9.6
[5] => -1.7
[6] => -6.2
)
You can use array_filter function,
$positive = array_filter($ts, function ($v) {
return $v > 0;
});
$negative = array_filter($ts, function ($v) {
return $v < 0;
});
Note: This will skip values with 0, or you can just change condition to >=0 in positive numbers filter to considered in positive group.
DEMO.
The most elegant is to use phps array_filter() function:
<?php
$ts = [ 7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7 ];
print_r( array_filter( $ts, function( $val ) { return (0>$val); } ) );
print_r( array_filter( $ts, function( $val ) { return ! (0>$val); } ) );
?>
If you are still using an older php version you need some longer implementation:
<?php
$ts = array( 7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7 );
print_r( array_filter( $ts, create_function( '$val', 'return (0>$val);' ) ) );
print_r( array_filter( $ts, create_function( '$val', 'return ! (0>$val);' ) ) );
?>
Food for thought, you could write a generic function that splits an array based on a boolean result:
// splits an array based on the return value of the given function
// - add to the first array if the result was 'true'
// - add to the second array if the result was 'false'
function array_split(array $arr, callable $fn)
{
$a = $b = [];
foreach ($arr as $key => $value) {
if ($fn($value, $key)) {
$a[$key] = $value;
} else {
$b[$key] = $value;
}
}
return [$a, $b];
}
list($positive, $negative) = array_split($ts, function($item) {
return $item >= 0;
});
print_r($positive);
print_r($negative);
Demo
Rather than declaring two arrays, I recommend declaring one array with two subarrays. You can either give the subarrays an index of 0 or 1 depending on the conditional evaluation with zero, or you can go a little farther by declaring a lookup array to replace the integer key with an expressive word.
Regardless of if you choose to create one array or two arrays, you should only make one loop over the input array. Making two loops or by calling array_filter() twice is needlessly inefficient.
Code: (Demo)
$ts = [7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7];
const KEY_NAMES = [0 => 'negative', 1 => 'non-negatuve'];
$result = [];
foreach ($ts as $v) {
$result[KEY_NAMES[$v >= 0]][] = $v;
}
var_export($result);
Output:
array (
'non-negatuve' =>
array (
0 => 7,
1 => 13,
2 => 8,
3 => 4,
4 => 3.5,
5 => 6.5,
6 => 7,
),
'negative' =>
array (
0 => -10,
1 => -7.2,
2 => -12,
3 => -3.7,
4 => -9.6,
5 => -1.7,
6 => -6.2,
),
)
Hi i am facing problem in sorting multidimensional array by different key,such as by date, by category, by weight in any specific order.
I can not order these array by mysql order by feature as i have to implement a tough business logic on mysql output array (data)..
After implementing business logic i found following type of array that need to be sorted by
date asc,category desc,weight asc.
array have size of 10000 or more.
i have already used usort function but it can't resolve issue of fixed ordering in case of same value of sorting elements.
plz help.
Array
(
[0] => Array
(
[categorie] => xyz
[date] => 2012-12-08 19:30
[weight] => 3
[row_id] => 125812
[searchtype] => show
[uitgespeeld] => 0
)
[1] => Array
(
[categorie] => show
[date] => 2012-12-10 20:15
[weight] => 3
[row_id] => 125816
[searchtype] => show
[uitgespeeld] => 0
)
[2] => Array
(
[categorie] => abc
[date] => 2012-12-13 20:30
[weight] => 3
[row_id] => 119151
[searchtype] => show
[uitgespeeld] => 0
)
.......
)
Code i have used for sorting.
usort($temp_group_data, array('className','cmp_weight'));
usort($temp_group_data, array('className','cmp_date'));
function cmp_weight($a, $b) {
if (($a['weight']==$b['weight']) ) {
return 0;
} else if ($a['weight'] >$b['weight']) {
return -1;
} else {
return 1;
}
}
function cmp_date($a, $b) {
if (($a['date']==$b['date']) ) {
return 0;
} else if (strtotime($a['date']) >strtotime($b['date'])) {
return -1;
} else {
return 1;
}
}
You have to do it in one function, now second sorting overwrites changes made in first.
function multicompare($a,$b){
$criteria = array(
'date' => 'asc',
'category' => 'desc',
'weight' => 'asc'
);
foreach($criteria as $what => $order){
if($a[$what] == $b[$what]){
continue;
}
return (($order == 'desc')?-1:1) * strcmp($a[$what], $b[$what]);
}
return 0;
}
The problem is two-fold, judging by the last part of your question:
All conditions must be evaluated at the same time rather than consecutively.
You need stable sorting to retain the ordering in case two values are the same (i.e. the original order)
Both steps in one goes like this; first you "decorate" the array using the index in which they appear in the original array:
foreach ($a as $key => &$item) {
$item = array($item, $key); // add array index as secondary sort key
}
usort($a, 'mysort'); // sort it
// undecorate
foreach ($a as $key => &$item) {
$item = $item[0]; // remove decoration from previous step
}
And here's the all-in-one sorting function:
function mysort($a, $b)
{
if ($a[0]['date'] != $b[0]['date']) {
return $a[0]['date'] < $b[0]['date'] ? -1 : 1; // ASC
} elseif ($a[0]['category'] != $b[0]['category']) {
return $a[0]['category'] < $b[0]['category'] ? 1 : -1; // DESC
} elseif ($a[0]['weight'] != $b[0]['weight']) {
return $a[0]['weight'] < $b[0]['weight'] ? -1 : 1; // ASC
} else {
return $a[1] < $b[1] ? -1 : 1; // ASC
}
}
I have the following array
[0] => Array
(
[id] => 229
[val] => 2
)
[3] => Array
(
[id] => 237
[val] => 1
)
[4] => Array
(
[id] => 238
[val] => 6
)
I need to sort this array according to the val values in the array, and do not know how to accomplish this?
function cmp($a, $b)
{
if ($a["val"] == $b["val"]) {
return 0;
}
return ($a["val"] < $b["val"]) ? -1 : 1;
}
usort($yourarray, "cmp");
Read this for more information.
array_multisort can help with this, example 3 presents a similar problem and solution.
This would help - http://www.informit.com/articles/article.aspx?p=341245&seqNum=7
You can use array_multisort()
Examples here: http://www.php.net/manual/en/function.array-multisort.php
The Example #3 Sorting database results is what you want. Might be easier if you are not familiar with callback functions and usort().
use this function to sort array accroding to your need
function sksort(&$array, $subkey="id",$sort_ascending=false)
{
if (count($array))
$temp_array[key($array)] = array_shift($array);
foreach($array as $key => $val){
$offset = 0;
$found = false;
foreach($temp_array as $tmp_key => $tmp_val)
{
if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey]))
{
$temp_array = array_merge(
(array)array_slice($temp_array,0,$offset),
array($key => $val),
array_slice($temp_array,$offset)
);
$found = true;
}
$offset++;
}
if(!$found) $temp_array = array_merge($temp_array, array($key => $val));
}
if ($sort_ascending) $array = array_reverse($temp_array);
else $array = $temp_array;
}
==========================================================================
now use this function in ur array
sksort($arrayname, "val"); /* for ascending */
sksort($arrayname, "val", true); /* for descending */