Sort Date array from txt file - php

I have a .txt file that store all the information from my form. And I want to have 1 php that display status from the oldest date to today's date.
This is some example of my txt format:
ID4494 (tab("\t")) 12/02/2008 (tab("\t")) ANJAY
ID4496 (tab("\t")) 14/04/2009 (tab("\t")) SONJA
ID4499 (tab("\t")) 19/03/2014 (tab("\t")) BRIAN
and this is my php file
$myfilename = "../idfile/digid.txt";
if( file_exists($myfilename) && filesize($myfilename) > 0 ) {
$digArray = file($myfilename, FILE_IGNORE_NEW_LINES);
sort($digArray);
foreach($digArray as $dig) {
$oneDigArray = explode("\t", $dig);
echo "<p>$oneDigArray[0] - $oneDigArray[1] - $oneDigArray[2]</p>";
}
} else {
echo "There is no Digital ID.";
}
I tried to use sort ($digArray[1]); since the date is array no. 1. But it wont work.
Any suggestion?
Thank you.

You can use PHP's usort function and supply your own comparison function. Like this:
function cmp($a, $b)
{
return ($a[1] > $b[1]) ? 1 : -1; // Ascending order
// OR
return ($a[1] < $b[1]) ? 1 : -1; // Descending order
}
usort($digArray, "cmp");
The above will sort your array by date. Here is a test I did.
Test:
$digArray = array(
array(
"ID4496", "14/04/2009", "SONJA"
),
array(
"ID4499", "19/03/2014", "BRIAN"
),
array(
"ID4494", "12/02/2008", "ANJAY"
),
);
function cmp($a, $b)
{
return ($a[1] > $b[1]) ? 1 : -1; // Ascending order
}
usort($digArray, "cmp");
print_r($digArray);
Output:
Array (
[0] => Array ( [0] => ID4494 [1] => 12/02/2008 [2] => ANJAY )
[1] => Array ( [0] => ID4496 [1] => 14/04/2009 [2] => SONJA )
[2] => Array ( [0] => ID4499 [1] => 19/03/2014 [2] => BRIAN )
)

Related

Sorting of multidimensional array with with numbers and letters

How to sort multidimensional array. This is what my array looks like
[0] => Array
(
[id] => 1
[title] => 3A
[active] => 1
)
[1] => Array
(
[id] => 1
[title] => A
[active] => 1
)
[2] => Array
(
[id] => 1
[title] => 2A
[active] => 1
)
[3] => Array
(
[id] => 1
[title] => B
[active] => 1
)
I have tried several usort methods, but cannot seem to get this to work. I am needing the array sorted so that it will sort by numeric then by alpha numeric like so: A,B,2A,3A.
I am not sure if this would be possible without adding a position field to dictate what order the titles are suppose to be in, or am I missing something here?
You can build a "key" for each item where the digit part is padded on the left with 0s, this way, the sort function can perform a simple string comparison:
$temp = [];
foreach ($arr as $v) {
$key = sscanf($v['title'], '%d%s');
if (empty($key[0])) $key = [ 0, $v['title'] ];
$key = vsprintf("%06d%s", $key);
$temp[$key] = $v;
}
ksort($temp);
$result = array_values($temp);
demo
This technique is called a "Schwartzian Transform".
As #Kargfen said, you can use usort with your custom function. Like this one :
usort($array, function(array $itemA, array $itemB) {
return myCustomCmp($itemA['title'], $itemB['title']);
});
function myCustomCmp($titleA, $titleB) {
$firstLetterA = substr($titleA, 0, 1);
$firstLetterB = substr($titleB, 0, 1);
//Compare letter with letter or number with number -> use classic sort
if((is_numeric($firstLetterA) && is_numeric($firstLetterB)) ||
(!is_numeric($firstLetterA) && !is_numeric($firstLetterB)) ||
($firstLetterA === $firstLetterB)
) {
return strcmp($firstLetterA, $firstLetterB);
}
//Letters first, numbers after
if(! is_numeric($firstLetterA)) {
return -1;
}
return 1;
}
This compare-function is just based on the first letter of your titles, but it can do the job ;-)
You can resolve that problem with help of usort and custom callback:
function customSort($a, $b)
{
if ($a['id'] == $b['id']) {
//if there is no number at the beginning of the title, I add '1' to temporary variable
$aTitle = is_numeric($a['title'][0]) ? $a['title'] : ('1' . $a['title']);
$bTitle = is_numeric($b['title'][0]) ? $b['title'] : ('1' . $b['title']);
if ($aTitle != $bTitle) {
return ($aTitle < $bTitle) ? -1 : 1;
}
return 0;
}
return ($a['id'] < $b['id']) ? -1 : 1;
}
usort($array, "customSort");
At first the function compares 'id' values and then if both items are equal it checks 'title' values.

PHP - Sort arrays by keys and values

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
)

Stable sort with multiple conditions

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
}
}

Array sort in PHP

How can I sort a 2D array in PHP.
I want to sort on date, Array is in this format :
[result] => Array
(
[0] => Array
(
[link] => http://local/node/0
[date] => 13158505310
)
[1] => Array
(
[link] => http://local/node/1
[date] => 13158505311
)
[2] => Array
(
[link] => http://local/node/2
[date] => 13158505312
Use usort:
usort( $array, function( $a, $b ){ return $a["date"] - $b["date"]; } );
Use this
function sortByDateDesc($a, $b) {
return strcmp($a["date"], $b["date"]);
}
function sortByDateAsc($a, $b) {
if ($a['date'] == $b['date']) {
return 0;
}
return ($a['date'] > $b['date']) ? -1 : 1;
}
usort($array, 'sortByDateDesc'); //Descending order
//usort($array, 'sortByDateAsc'); //Asceding order
Use http://nl.php.net/manual/en/function.usort.php
You could also try multisort http://www.php.net/manual/en/function.array-multisort.php
may be this code helpful to you....
// Obtain a list of columns
foreach (data as key => row) {
links[key] = row['link'];
dates[key] = row['date'];
}
// Sort the data with link descending, date ascending
// Add $data as the last parameter, to sort by the common key
array_multisort(link, SORT_DESC, date, SORT_ASC, data);

Help me sort this php array using usort()

I have a data structure that looks like
Array
(
[0] => Array
(
[0] => something
[1] => 1296986500
)
[1] => Array
(
[0] => something else
[1] => 1296600100
)
[2] => Array
(
[0] => another thing
[1] => 1296831265
)
)
I'm trying to sort the array based off of the integer which is a unix timestamp. The following function looks right to me but is not sorting the way I want.
function cmp($a, $b)
{
if ($a[1] == $b[1]) {
return 0;
}
return ($a[1] < $b[1]) ? -1 : 1;
}
NOTE
when calling this function within a class the OO syntax is the following
uasort($_data, array($this, 'cmp'));
That sorts your timestamps in ascending order; for descending order, flip the second comparison (i.e. change $a[1] < $b[1] to $a[1] > $b[1]):
function cmp($a, $b)
{
if ($a[1] == $b[1]) {
return 0;
}
return ($a[1] > $b[1]) ? -1 : 1;
}
You can setup time stamp as pivot. And use array_multisort().
<?php
// Obtain a list of columns
foreach ($data as $key => $row) {
$time[$key] = $row[1]; //unix timestamp
}
array_multisort( $time, SORT_ASC, $data);
?>

Categories