我需要使用日期对数组进行排序,但问题是第一个数组将该值存储在键added_date
中,而第二个数组使用键date_added
。
如何根据日期对它们进行排序(首先是较新的元素)?
该数组具有以下结构:
[0] => Array
(
[data] => Array
(
[0] => Array
(
[media] => upcomingEvents_1214_1429325758.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:00
[type] => image/jpeg
)
[1] => Array
(
[media] => upcomingEvents_1214_1429325809.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:51
[type] => image/jpeg
)
[2] => Array
(
[media] => diary_1214_1434190391.jpeg
[reference] => diary
[added_date] => 2015-06-13 15:43:11
[type] => image/jpeg
)
)
[identifier] => media
)
[1] => Array
(
[data] => Array
(
[0] => Array
(
[media] => image.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 08:38:09
[chat_type] => image/jpeg
)
[1] => Array
(
[media] => 1432787219556.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 17:45:45
[chat_type] => image/jpeg
)
[2] => Array
(
[media] => 1436160762565.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-07-06 09:03:27
[chat_type] => image/jpeg
)
)
[identifier] => chat
)
答案 0 :(得分:2)
通常,您应首先展平阵列,以便更轻松地对其进行排序。
一旦您将维度降低到具有date_added
或added_date
的合理平面数组,您就可以使用usort
来检查两者的现有密钥然后比较它们。
这是一个略微简化的样本:
<?php
$arr = array(
array(
'data' => array(
array('date_added' => 3),
array('date_added' => 1),
array('date_added' => 6)
)
),
array(
'data' => array(
array('added_date' => 4),
array('added_date' => 0),
array('added_date' => 5)
)
)
);
function normalize($arr_elem) {
return $arr_elem['data'];
}
function sort_by_date($a, $b) {
$dateA = array_key_exists('date_added', $a) ? $a['date_added'] : $a['added_date'];
$dateB = array_key_exists('date_added', $b) ? $b['date_added'] : $b['added_date'];
return $dateA > $dateB;
}
$flattened = array_reduce(array_map('normalize', $arr), 'array_merge', array());
usort($flattened, 'sort_by_date');
var_dump($flattened);
?>
答案 1 :(得分:1)
usort
应用于子数组的data
键。usort
查看密钥date_added
或added_date
是否可用,获取值,将其转换为dateTime
个对象并进行比较以返回排序顺序。 由于您没有说明合并各种data
数组,因此该解决方案保留了原始结构。
// the function
function sortByDate(&$arr) {
$callback = function($a, $b) {
if(isset($a['added_date'])) {
$key = 'added_date';
}
elseif(isset($a['date_added'])) {
$key = 'date_added';
}
else {
return 0;
}
$d1 = DateTime::createFromFormat('Y-m-d H:i:s', $a[$key]);
$d2 = DateTime::createFromFormat('Y-m-d H:i:s', $b[$key]);
return ($d1 < $d2) ? 1 : -1;
};
foreach($arr as &$subArr) {
usort($subArr['data'], $callback);
}
}
// the data as JSON, provided for reproducibility
$arr = json_decode('[{"data":[
{"media":"upcomingEvents_1214_1429325758.jpeg","reference":"upcomingEvents","added_date":"2015-04-18 08:26:00","type":"image\/jpeg"},
{"media":"diary_1214_1434190391.jpeg","reference":"diary","added_date":"2015-06-13 15:43:11","type":"image\/jpeg"},
{"media":"upcomingEvents_1214_1429325809.jpeg","reference":"upcomingEvents","added_date":"2015-04-18 08:26:51","type":"image\/jpeg"}
],"identifier":"media"},
{"data":[
{"media":"1432787219556.jpg","media_thumb":"","couple_id":"312","date_added":"2015-06-22 17:45:45","chat_type":"image\/jpeg"},
{"media":"1436160762565.jpg","media_thumb":"","couple_id":"312","date_added":"2015-07-06 09:03:27","chat_type":"image\/jpeg"},
{"media":"image.jpg","media_thumb":"","couple_id":"312","date_added":"2015-06-22 08:38:09","chat_type":"image\/jpeg"}
],"identifier":"chat"}]', true);
// testing
print_r($arr);
sortByDate($arr);
echo "--- sorted ---\n";
print_r($arr);
Array
(
[0] => Array
(
[data] => Array
(
[0] => Array
(
[media] => upcomingEvents_1214_1429325758.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:00
[type] => image/jpeg
)
[1] => Array
(
[media] => diary_1214_1434190391.jpeg
[reference] => diary
[added_date] => 2015-06-13 15:43:11
[type] => image/jpeg
)
[2] => Array
(
[media] => upcomingEvents_1214_1429325809.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:51
[type] => image/jpeg
)
)
[identifier] => media
)
[1] => Array
(
[data] => Array
(
[0] => Array
(
[media] => 1432787219556.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 17:45:45
[chat_type] => image/jpeg
)
[1] => Array
(
[media] => 1436160762565.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-07-06 09:03:27
[chat_type] => image/jpeg
)
[2] => Array
(
[media] => image.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 08:38:09
[chat_type] => image/jpeg
)
)
[identifier] => chat
)
)
--- sorted ---
Array
(
[0] => Array
(
[data] => Array
(
[0] => Array
(
[media] => diary_1214_1434190391.jpeg
[reference] => diary
[added_date] => 2015-06-13 15:43:11
[type] => image/jpeg
)
[1] => Array
(
[media] => upcomingEvents_1214_1429325809.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:51
[type] => image/jpeg
)
[2] => Array
(
[media] => upcomingEvents_1214_1429325758.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:00
[type] => image/jpeg
)
)
[identifier] => media
)
[1] => Array
(
[data] => Array
(
[0] => Array
(
[media] => 1436160762565.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-07-06 09:03:27
[chat_type] => image/jpeg
)
[1] => Array
(
[media] => 1432787219556.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 17:45:45
[chat_type] => image/jpeg
)
[2] => Array
(
[media] => image.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 08:38:09
[chat_type] => image/jpeg
)
)
[identifier] => chat
)
)
答案 2 :(得分:0)
就个人而言,我更喜欢OO方法:)
<?php
date_default_timezone_set('Europe/London');
class ArraySort {
private $unsortedArray = array();
private $sortedArray = array();
private static $dateKeySynonym = array('added_date', 'date_added');
public function __construct($unsortedArray) {
$this->unsortedArray = $unsortedArray;
}
public function doSort() {
$outputArray = array();
foreach ($this->unsortedArray as $cell) {
$identifier = $cell['identifier'];
foreach ($cell['data'] as $subCell) {
// must keep the identifier : don't loose it !!
$subCell['identifier'] = $identifier;
$outputArray[] = $subCell;
}
}
usort($outputArray, array('ArraySort', '_sort'));
$this->sortedArray = $outputArray;
}
public function getSortedArray() {
return $this->sortedArray;
}
private static function _sort($a, $b) {
$date1 = NULL;
$date2 = NULL;
foreach(self::$dateKeySynonym as $dateKeySynonym) {
if (isset($a[$dateKeySynonym])) {
$date1 = new DateTime($a[$dateKeySynonym]);
break;
}
}
foreach(self::$dateKeySynonym as $dateKeySynonym) {
if (isset($b[$dateKeySynonym])) {
$date2 = new DateTime($b[$dateKeySynonym]);
break;
}
}
return ($date1 < $date2);
}
}
// ---------------------- test class ---------------------------
$a[0]['identifier'] = 'media';
$cell['media'] = 'upcomingEvents_1214_1429325758.jpeg';
$cell['reference'] = 'upcomingEvents';
$cell['added_date'] = '2015-04-18 08:26:00';
$cell['type'] = 'image/jpeg';
$a[0]['data'][] = $cell;
$cell['media'] = 'upcomingEvents_1214_1429325809.jpeg';
$cell['reference'] = 'upcomingEvents';
$cell['added_date'] = '2015-04-18 08:25:51';
$cell['type'] = 'image/jpeg';
$a[0]['data'][] = $cell;
$cell['media'] = 'diary_1214_1434190391.jpeg';
$cell['reference'] = 'diary';
$cell['added_date'] = '2015-06-13 15:43:11';
$cell['type'] = 'image/jpeg';
$a[0]['data'][] = $cell;
// -----------------------------------------------------------
unset($cell);
// -----------------------------------------------------------
$a[1]['identifier'] = 'chat';
$cell['media'] = 'image.jpg';
$cell['media_thumb'] = '';
$cell['couple_id'] = 312;
$cell['date_added'] = '2015-06-22 08:38:09';
$cell['chat_type'] = 'image/jpeg';
$a[1]['data'][] = $cell;
$cell['media'] = '1436160762565.jpg';
$cell['media_thumb'] = '';
$cell['couple_id'] = 312;
$cell['date_added'] = '2015-07-06 09:03:27';
$cell['chat_type'] = 'image/jpeg';
$a[1]['data'][] = $cell;
// -------------------------------------------------------------
$arraySort = new ArraySort($a);
$arraySort->doSort();
var_dump($arraySort->getSortedArray());
答案 3 :(得分:0)
这适用于(对我来说)但是破坏了你的数组结构而你丢失了[identifier]键。 我使用[&#39; id&#39;]检查订单,如果我更改了主题填写的顺序,输出将保持不变(排序:最新的):< / p>
$subject = array(
array( 'data' => array(
array( 'id' => 1 , 'added_date' => '2015-04-18 08:26:00' ) ,
array( 'id' => 2 , 'added_date' => '2015-04-18 08:26:51' ) ,
array( 'id' => 3 , 'added_date' => '2015-06-13 15:43:11' ) ,
) ) ,
array( 'data' => array(
array( 'id' => 4 , 'date_added' => '2015-06-22 08:38:09' ) ,
array( 'id' => 5 , 'date_added' => '2015-06-22 17:45:45' ) ,
array( 'id' => 6 , 'date_added' => '2015-07-06 09:03:27' ) ,
) ) );
$dates = array();
foreach ($subject as $k1=>$d1) {
foreach ($d1['data'] as $k3=>$d3) {
if(isset($d3['date_added'])) array_push($dates, $d3['date_added'].'|'.$k1.'|'.$k3);
if(isset($d3['added_date'])) array_push($dates, $d3['added_date'].'|'.$k1.'|'.$k3);
}
}
rsort($dates, SORT_STRING );
$sorted = array();
foreach ($dates as $val) {
preg_match('/([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9])\|([0-9]+)\|([0-9]+)/',$val, $matches);
array_push($sorted, $subject[$matches[2]]['data'][$matches[3]]);
}
$result= array();
foreach ($sorted as $key => $val) {
$result[(count($sorted)-1)-$key]=$val;
}
print_r($result); // < This prints the array
如果此解决方案不适合您,请发表评论,我会尝试调整。
答案 4 :(得分:0)
正如其他人所指出的那样,我不确定你期望的是什么输出。这里给出的数组是一个媒体元素数组,只按日期排序。它们采用相同的格式,现在只是一个二维数组。它使用合并排序来对数组元素进行排序。我没有测试这段代码,但这应该足以满足您的需求。我们使用Splqueue类来帮助对元素进行排序:
$searchQueue = new SplQueue(); // we will store our media nodes here
$sortedQueue = new SplQueue(); // we will have our sorted array nodes here
我们的第一个函数将找到媒体元素并将它们放入队列
function findArrays($someArray) {
foreach ($someArray as $anArray) {
if (array_key_exists("type", $anArray) {
// bottom level array
$searchQueue.enqueue($anArray);
}
else {
$searchQueue.enqueue(sortArrays($anArray));
}
}
}
下一个函数将对这些媒体元素进行粒化并且是递归的。一旦它被粒化成单个细胞,该功能就会通过我们的下一个功能开始排序......
function mergeSort($someQueue){
if ($someQueue.count() <= 1 {
return $someQueue;
}
$left = new SplQueue();
$right = new SplQueue();
$middle = (int)$someQueue.count() / 2;
for ($x = 0; $x < $middle; $x++){
$left.queue($someQueue.dequeue());
}
for ($x = 0; $x < $someQueue.count(); $x++){
$right.queue($someQueue.dequeue());
}
$sortedLeft = mergeSort($left);
$sortedRight = mergeSort($right);
return merge($sortedLeft, $sortedRight); // calls the sorting function
}
最终的功能是对元素进行实际排序。它需要两个队列并比较它们的值。
function merge($left, $right){
$result = new SplQueue();
$dateTimeFormat = "Y-m-d H:i:s";
while (!$left.isEmpty() && !$right.isEmpty()) {
// find what we are going to compare to what (added_date or date_added)
$leftVal;
$rightVal;
if (array_key_exists("added_date", $left.bottom())) {
$leftVal = DateTime::createFromFormat($dateTimeFormat, $left.bottom()["added_date"]);
}
else {
$leftVal = DateTime::createFromFormat($dateTimeFormat, $left.bottom()["date_added"]);
}
if (array_key_exists("added_date", $right.bottom())) {
$rightVal = DateTime::createFromFormat($dateTimeFormat, $right.bottom()["added_date"]);
}
else {
$rightVal = DateTime::createFromFormat($dateTimeFormat, $right.bottom()["date_added"]);
}
// $leftVal and $rightVal now contain the values we are going to compare
if ($leftVal < $rightVal) {
$result.enqueue($left.dequeue());
}
else {
$result.enqueue($right.dequeue());
}
}
while (!$left.isEmpty()) {
$result.enqueue($left.dequeue());
}
while (!$left.isEmpty()) {
$result.enqueue($right.dequeue());
}
return $result;
}
这两个函数与定义的队列一起使用以生成排序队列。然后将该队列移回一个数组。
// bread and butter
findArrays($yourArrays);
$sortedMediaNodes = mergeSort($searchQueue); // sorted media nodes in a queue
$arrayResults = array(); // will contain an array of the $sortedMediaNodes queue
while (!$sortedMediaNodes.isEmpty()) {
$arrayResults[] = $sortedMediaNodes.dequeue();
}
我不太确定这是否是您想要的,但无论上述功能是合并排序还是在需要时派上用场。
答案 5 :(得分:0)
由于OP没有说明输出的数组结构,我假设它应该与输入结构相同。此外,我认为所有条目都应按日期排序,与其类型(聊天或媒体)无关。
以下算法分三步:
这样做的优点是我们可以混合类型并对它们进行排序而不会丢失结构。
// Deflate array
function deflate($arr)
{
$deflated = array();
foreach($arr as $dataGroup) {
foreach ($dataGroup['data'] as $item) {
$item['identifier'] = $dataGroup['identifier'];
$deflated[] = $item;
}
}
return $deflated;
}
// Inflate array
function inflate($arr)
{
$inflated = array();
$lastIdentifier = NULL;
foreach ($arr as $item) {
if ($item['identifier'] != $lastIdentifier) {
if (isset($dataGroup)) {
$dataGroup['identifier'] = $lastIdentifier;
}
unset($dataGroup);
$dataGroup = array();
$inflated[] = &$dataGroup;
}
$lastIdentifier = $item['identifier'];
unset($item['identifier']);
$dataGroup['data'][] = $item;
}
if (isset($dataGroup)) {
$dataGroup['identifier'] = $lastIdentifier;
}
return $inflated;
}
// Sort deflated array by date
function sortArray(&$arr)
{
$callback = function($a, $b)
{
if(isset($a['added_date'])) {
$aDate = $a['added_date'];
} elseif(isset($a['date_added'])) {
$aDate = $a['date_added'];
} else {
$aDate = '';
}
if(isset($b['added_date'])) {
$bDate = $b['added_date'];
} elseif(isset($b['date_added'])) {
$bDate = $b['date_added'];
} else {
$bDate = '';
}
return ($aDate < $bDate) ? 1 : -1;
};
usort($arr, $callback);
}
// Test output
print_r($arr);
// 1. step: deflate array
$arr = deflate($arr);
// echo "--- deflated ---\n";
// print_r($arr);
// 2. step: sort deflated array
sortArray($arr);
// echo "--- deflated and sorted ---\n";
// print_r($arr);
// 3. step: inflate sorted array
$arr = inflate($arr);
echo "--- sorted and inflated ---\n";
print_r($arr);
您可以在打印行中注释,以便在排序前后查看平面阵列。
Array
(
[0] => Array
(
[data] => Array
(
[0] => Array
(
[media] => upcomingEvents_1214_1429325758.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:00
[type] => image/jpeg
)
[1] => Array
(
[media] => upcomingEvents_1214_1429325809.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:51
[type] => image/jpeg
)
[2] => Array
(
[media] => diary_1214_1434190391.jpeg
[reference] => diary
[added_date] => 2015-06-13 15:43:11
[type] => image/jpeg
)
)
[identifier] => media
)
[1] => Array
(
[data] => Array
(
[0] => Array
(
[media] => image.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 08:38:09
[chat_type] => image/jpeg
)
[1] => Array
(
[media] => 1432787219556.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 17:45:45
[chat_type] => image/jpeg
)
[2] => Array
(
[media] => 1436160762565.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-07-06 09:03:27
[chat_type] => image/jpeg
)
)
[identifier] => chat
)
)
--- sorted and inflated ---
Array
(
[0] => Array
(
[data] => Array
(
[0] => Array
(
[media] => 1436160762565.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-07-06 09:03:27
[chat_type] => image/jpeg
)
[1] => Array
(
[media] => 1432787219556.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 17:45:45
[chat_type] => image/jpeg
)
[2] => Array
(
[media] => image.jpg
[media_thumb] =>
[couple_id] => 312
[date_added] => 2015-06-22 08:38:09
[chat_type] => image/jpeg
)
)
[identifier] => chat
)
[1] => Array
(
[data] => Array
(
[0] => Array
(
[media] => diary_1214_1434190391.jpeg
[reference] => diary
[added_date] => 2015-06-13 15:43:11
[type] => image/jpeg
)
[1] => Array
(
[media] => upcomingEvents_1214_1429325809.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:51
[type] => image/jpeg
)
[2] => Array
(
[media] => upcomingEvents_1214_1429325758.jpeg
[reference] => upcomingEvents
[added_date] => 2015-04-18 08:26:00
[type] => image/jpeg
)
)
[identifier] => media
)
)
对于使用过的数组,似乎对只对内部数组进行排序的解决方案没有太大区别。但是如果你有混合类型的日期,那将会有所不同。例如,比聊天项更新的媒体项和更旧的另一媒体项。在显示的输出中,所有媒体项都比聊天项旧。
感谢AVGP和花钱。他们用我们的答案启发了我的解决方案:AVGP's flat solution和spendious's sorting of the inner arrays。