How to sort multidimensional array by name/timestamp? [duplicate] - php

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 5 years ago.
I were using the "rsort" function to sort through the timestamps when the array only contained a timestamp and were not multidimensional.
So now the question is how do i approach this?
The array looks something similair to this
Array
(
[0] => Array
(
[type] => post
[id] => 1
[timestamp] => 2017-08-12 21:03:22
[poster] => 1
[profile] => 1
[post] => Testtttttinngggs
)
[1] => Array
(
[type] => post
[id] => 2
[timestamp] => 2017-08-12 21:03:18
[poster] => 1
[profile] => 5
[post] => Hello you
)
[2] => Array
(
[type] => post
[id] => 3
[timestamp] => 2017-08-12 21:03:33
[poster] => 1
[profile] => 1
[post] => Somesay timestamp is screwed
)
[3] => Array
(
[type] => post
[id] => 4
[timestamp] => 2017-08-12 21:28:54
[poster] => 1
[profile] => 1
[post] => This is truely a teeest
)
[4] => Array
(
[type] => post
[id] => 5
[timestamp] => 2017-08-13 15:04:34
[poster] => 1
[profile] => 1
[post] => Test test test test
)
)

You can use array_multisort
array_multisort(array_column($list, 'timestamp'), SORT_ASC, $list);

You can use usort
usort($array, function($a, $b)
{
if($a['timestamp']>$b['timestamp'])
{
return -1;
}
elseif($a['timestamp']<$b['timestamp'])
{
return 1;
}
return 0;
});

Update
I was wrong. Axalix' answer runs a lot faster than mine and Rob Ruchte's. My tests:
$data = [
['timestamp'=> '2015-08-12', 'id'=>1],
['timestamp'=> '2017-07-13', 'id'=>2],
['timestamp'=> '2017-01-12', 'id'=>3],
];
function useUsort($data){
usort($data,function($a,$b) {
return strtotime($b['timestamp']) - strtotime($a['timestamp']);
});
};
function useMultisort($data){
array_multisort(array_column($data, 'timestamp'), SORT_DESC, $data);
};
$start = microtime(true);
for($i=1;$i<=100000;$i++) useUsort($data);
$t1 = microtime(true);
for($i=1;$i<=100000;$i++) useMultisort($data);
$t2 = microtime(true);
echo "usort: ". round(($t1 - $start) * 1000) . " ms\n";
echo "array_multisort: ". round(($t2 - $t1) * 1000) . " ms\n";
My result:
usort: 2262 ms
array_multisort: 246 ms
Original answer
#Axalix' answer is nice but I would take a different approach. Because you only care about sorting by one field (timestamp), array_multisort is overkill as it was design to sort by multiple fields. I would do:
usort($data,function($a,$b) {
return strtotime($b['timestamp']) - strtotime($a['timestamp']);
});
Live demo
This will easily outperform array_multisort because it doesn't require PHP to first extract the timestamp into a separate column array, and then execute the multisort (a more complex function than my simple comparator function) on it.

Related

How to sort an multidimensional array using Php? [duplicate]

This question already has answers here:
How to Sort a Multi-dimensional Array by Value
(16 answers)
Closed 6 years ago.
I have an multidimensional array and want to sort in according to date and also want to get only 5 data from an array.
Array :
Array
(
[0] => Array
(
[ID] => 1
[TITLE] => example1
[DATE] => 2016-05-17
[PST_BY] => 0
[IMG_NM] =>
[SLUG] =>
[NAME] => Web Design & Development
)
[1] => Array
(
[ID] => 2
[TITLE] => example2
[DATE] => 2016-05-20
[PST_BY] => 0
[IMG_NM] =>
[SLUG] =>
[NAME] => Mobile OS
)
)
I am doing this but not working :
$list = array_sort($blog, 'DATE', SORT_ASC);
print_r($list);
Example to sort on a specific key (in this case name):
// Function to compare two items in the array
function CompareName($left, $right) {
return $left['name'] > $right['name'];
}
// Example array/data
$myarray = [
["id"=>1, "name"=>"foo"],
["id"=>2, "name"=>"bar"],
["id"=>3, "name"=>"ah"],
["id"=>4, "name"=>"zoo"]
];
echo 'Unsorted:';
var_dump($myarray);
usort($myarray , 'CompareName');
echo 'Sorted:';
var_dump($myarray);
want to get only 5 data from an array
$top5 = array_slice($myarray, 0, 5);
or:
$top5 = array_splice($myarray, 0, 5);

Formatting an array to order by specified unix timestamp in PHP

I have an array which has a timestamp consistently on [3] ( an example of the array data below)
I would like the array to be sorted using the timestamp. I've seen a few stackoverflow posts that apparently do this using two methods, array_multisort() and usort() but I've been unable to replicate either.
Here is what I've tried based on my own code:
Attempt 1 - I pass the array to usort, then attempt to take it apart with the foreach. Applying this method definitely changes the order of the results, but the dates seems to be no specific order (ascending, descending).
function sortArray($a1, $a2){
if ($a1[3] == $a2[3]) return 0;
return ($a1[3] > $a2[3]) ? -1 : 1;
}
usort($the_array, "sortArray");
foreach($the_array as $sh) {
$uid = $sh['uid'];
$username = $sh['username'];
$datetime = $sh['datetime'];
$type = $sh['type'];
echo "<p> $uid , $username, $datetime, $type </p>";
}
Attempt 2 - tried using array_multisor() which again gives me results in a different order but I don't understand what it is sorting by exactly.
foreach ($the_array as $key => $node) {
$timestamps[$key] = $node[3];
}
array_multisort($timestamps, SORT_ASC, $the_array);
//process the array with a foreach to show results
My theory here is that it isn't properly processing the unix timestamp and I'm not sure what I can do about that. Is it smart to take out all the characters of the timestamp so it is a simple line of numbers ( 2014-01-02 03:02:12 becomes 20140102030212 )? Or is there another way to process it with the timestamp in it's current form?
Here is an example of the data in the array:
Array
(
[0] => Array
(
[uid] => 20013
[0] => 20013
[username] => myhipswontlie
[1] => myhipswontlie
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-27 23:40:56
[3] => 2014-01-27 23:40:56
[type] => rated
[4] => rated
)
[1] => Array
(
[uid] => 20025
[0] => 20025
[username] => brasilchika
[1] => brasilchika
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-02 03:02:12
[3] => 2014-01-02 03:02:12
[type] => rated
[4] => rated
)
[2] => Array
(
[uid] => 10002
[0] => 10002
[username] => crtten
[1] => crtten
[datetime] => 2014-01-25 01:33:34
[2] => 2014-01-25 01:33:34
[type] => visits
[3] => visits
)
)
Your issue is your numeric keys don't seem to match up in your arrays. Sometimes the datetime is found in the 3rd key, sometime it is found in the second key (which is odd considering they look like they come from mysql_fetch_array() which will make uniform arrays).
To solve this you should use the associative array key instead:
function sortArray($a1, $a2){
if ($a1['datetime'] == $a2['datetime']) return 0;
return ($a1['datetime'] > $a2['datetime']) ? -1 : 1;
}
usort($the_array, "sortArray");

Sorting array of array by value in php [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I have an array named as $result which have contents something like this:
Array (
[1114_435] => stdClass Object
(
[uid] => 435
[v_first_name] => fHerter
[v_last_name] => Herter
[id] => 1114
[v_title] => Morning Stretch
[fk_resident_id] => 435
[v_location] => Front Lawn
[i_started_date] => 1357054200
)
[1114_444] => stdClass Object
(
[uid] => 444
[v_first_name] => fXYZ
[v_last_name] => XYZ
[id] => 1114
[v_title] => Morning Stretch
[fk_resident_id] => 444
[v_location] => Front Lawn
[i_started_date] => 1357054200
)
[1114_448] => stdClass Object
(
[uid] => 448
[v_first_name] => fDavidson
[v_last_name] => Davidson
[id] => 1114
[v_title] => Dinner
[fk_resident_id] => 448
[v_location] => Front Lawn
[i_started_date] => 1357051000
)
)
I want to sort it on the basis of i_started_date. I tried using ksort, asort etc but no luck, maybe i wasn`t using it properly. Any help would be highly appreciated.
Thanks!
Try something like this:
function sortArray($data)
{
$sortArray = array();
foreach($data as $dt)
{
foreach($dt as $key=>$value)
{
if(!isset($sortArray[$key]))
{
$sortArray[$key] = array();
}
$sortArray[$key][] = $value;
}
}
$orderby = "1"; //change this to whatever key you want from the array
array_multisort($sortArray[$orderby],SORT_ASC,$data);
return $data;
}

Sorting multidimensial array by two values containing numbers and letters

I have an array which looks like
[0] => Array
(
[typeName] => Element
[quantity] => 35
[flag] => 4
)
I already found a way by using usort() to sort an array by its sub elements. Which works great for numeric values.
public static function _sortByAmount($a, $b) {
return $b['quantity'] - $a['quantity'];
}
From time to time, it could happen that I have more than one array elements with the same quantity. Those entries should be sorted by the Name too. In the end, the array should look like this.
[0] => Array
(
[typeName] => Element
[quantity] => 567
[flag] => 4
)
[1] => Array
(
[typeName] => aaa-element
[quantity] => 35
[flag] => 4
)
[2] => Array
(
[typeName] => bbb-element
[quantity] => 35
[flag] => 4
)
[3] => Array
(
[typeName] => Element
[quantity] => 10
[flag] => 4
)
Is it possible to extend my function somehow?
You can check anything you want in your compare function. For example, if quantity == quantity then return strcmp.
public static function _sortByAmount($a, $b) {
if($b['quantity'] == $a['quantity']){
return strcmp($a['typeName'], $b['typeName']);
} else {
return $b['quantity'] - $a['quantity'];
}
}
you can also use strcasecmp if you want the check to be case insensitive.
not sure, but
public static function _sortByAmount($a, $b) {
$byQuantity = $a['quantity'] - $b['quantity'];
return $byQuantity ?: strcmp($a['typeName'], $b['typeName']);
}

PHP: Sorting Multi-Array Result [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I sort a multidimensional array in php
Array ( [0] => Array (
[card_name] => CardA
[str] => 10
[def] => 10
[desc] => - Recover 150 points of vitality
- Attack twice"
[qty] => 5
)
[1] => Array (
[card_name] => CardD
[str] => 40
[def] => 40
[desc] => - Investigate enemy's weakpoint
[qty] => 3
)
[2] => Array ( [card_name] => CardG
[str] => 35
[def] => 20
[desc] =>
[qty] => 1
)
[3] => Array (
[card_name] => CardH
[str] => 25
[def] => 30
[desc] =>
[qty] => 1
)
[4] => Array (
[card_name] => CardI
[str] => 15
[def] => 40
[desc] => - Enhance strength
[qty] => 1
)
[5] => Array (
[card_name] => CardJ
[str] => 5
[def] => 50
[desc] => - Make silence
[qty] => 3
)
)
I have a simple question about sorting arrays. I just want to sort the array in either by str or def in either asc or desc. The examples in the php.net is a bit confusing and I was wondering if anyone can solve this small dilemma.
I know I should be using array_multi_sort for this.
Thanks.
Use the usort function. It will be something like this in your case :
function compare($valueA, $valueB) {
if ($valueA['str'] > $valueb['str']) {
return 1;
} else if ($valueA['str'] < $valueb['str']) {
return -1;
}
return 0;
}
usort($yourArray, "compare");
Try php usort - http://www.php.net/manual/en/function.usort.php
I've not tried and run the code but it'll be something below:
function cmp($a, $b)
{
return strcmp($a['def'],$b['def'])
}
$a = yourArray[];
usort($a, "cmp");
This will iterate through each element and pass the array element as a parameter and will use your custom function to sort.
usort() and strnatcmp() is your solution:
<?php
function build_sorter($key) {
return function ($a, $b) use ($key) {
return strnatcmp($a[$key], $b[$key]);
};
}
usort($array, build_sorter('def'));
print_r($array);
?>
It will sort all arrays by your defined key.
Array multisort requires you to build an array holding the values of the keys you want to sort by to do what you want, but with the same first dimension keys of the original array.
Thus if you make an array which holds 0 => 10, 1 => 5... etc where those are the values for str or def for keys 0 and 1, then you can do
foreach($originalArray as $key => $record) {
$keyValuesArray[$key] = $record['str'];
}
array_multisort($keyvaluesArray, SORT_ASC, $originalArray);
And original array would be modified to be sorted.
As for what you should be doing, I don't think array multisort is "the way" to do it, but is not a terrible way of doing it. Other solutions might be slightly more efficient.

Categories