Делаю выборку следующим образом
//ищем в news и ThisDay и сливаем два массива вместе
$mergeResult = array_merge(
//выборка из таблицы thisDay
ThisDay::find()
->where(
new Expression(
"day = :dateDay"
. " AND id_region = :id_region", [":dateDay" =>
$dateDay,
":id_region" => REGION_ID]))
->orderBy("news_date DESC")
->all(),
//поиск по таблице News с лимитом 4 - (минус) кол-во новостей в ThisDay
News::find()
->alias("n")
->where(
//выборка по дню
new Expression("EXTRACT(DAY FROM cdate) = :userDay "
// выборка по региону,
. "AND id_region = :id_region "
// выборка по месяцу,
. "AND EXTRACT(MONTH FROM cdate) = :userMonth "
// выборка по году,
. "AND EXTRACT(YEAR FROM cdate) "
// выборка по статусу,
. "AND status > :stat AND n.id NOT IN"
//и чтобы id не совпадало с id из таблицы this_day
. " (SELECT id_news FROM this_day)",
//агрументы для бандинга
[":userDay" => $dateDay,
":userMonth" => $currentMoth,
":id_region" => REGION_ID,
":stat" => 1]))
//новости с самым высоким рейтингом
->joinWith("rating nr")
->orderBy("nr.rate DESC")
->limit(4 - ThisDay::find()
->where(
new Expression(
"day = :dateDay"
. " AND id_region = :id_region", [":dateDay" =>
$dateDay,
":id_region" => REGION_ID]))
->count())
//группировка и сортировка по дате
->orderBy("cdate_int DESC")
->groupBy("EXTRACT(YEAR FROM cdate)")
->all());
Получаю массив, далее индексирую его
//индексирую, если ThisDay
$indexedThisDay = ArrayHelper::index($mergeResult, function ($element) {
if ($element instanceof ThisDay) {
return (int) \Yii::$app->formatter->asDate($element['news_date'], 'yyyy');
}
});
//индексирую, если News
$indexedNews = ArrayHelper::index($mergeResult, function ($element) {
if ($element instanceof News) {
return (int) \Yii::$app->formatter->asDate($element['cdate_int'], 'yyyy');
}
});
Затем сортирую его примерно так arsort($model, SORT_NUMERIC); был еще вот такой вариант
$model = array_merge($indexedNews, $indexedThisDay);
и затем опять arsort($model, SORT_NUMERIC);
получаю массив с ключами
int(1) "0" int(1) "1" int(1) "2" int(1) "3" в в которых год расположен
2017, 2016, 2017, 2016 или 2016, 2017, 2016, 2017 как можно отсортировать массив так, чтобы они встали по убыванию даты? Чтобы получилось 2016, 2016, 2017, 2017. Т.е элементы не сортируются по убыванию/возрастанию вместе, они это делают каждый отдельно, а нужно, чтобы они отсортировались как один массив.
UPD: Я пытался использовать это
$model = array_merge($indexedNews, $indexedThisDay);
usort($model, function($arr1, $arr2) {
$dateThisDay = strtotime($arr1['news_date']);
$dateNews = strtotime($arr2['cdate_int']);
if ($dateThisDay == $dateNews)
return 0;
return ($dateThisDay < $dateNews) ? -1 : 1;
});
Но получаю ошибку Getting unknown property: ********\News::news_date поле news_date принадлежит ThisDay а он его ищет в News
Думаю вам поможет этот алгоритм сортировки:
function sortBy( $field, $array ) {
usort( $array, function ( $item1, $item2 )use( $field ) {
if ( $item1[ $field ] == $item2[ $field ] ) return 0;
return $item1[ $field ] < $item2[ $field ] ? -1 : 1;
} );
return true;
}
Где:
$field - это ключ по которому хотите отсортировать$array - исходный массив$arr = [
0 => 2017,
1 => 2016,
2 => 2017,
3 => 2016
];
asort($arr, SORT_NUMERIC); //по возрастанию, сохраняя ключи
sort($arr, SORT_NUMERIC); //по возрастанию, не сохраняя ключи
arsort($arr, SORT_NUMERIC); //по убыванию, сохраняя ключи
rsort($arr, SORT_NUMERIC); //по убыванию, не сохраняя ключи
var_dump($arr);
Сборка персонального компьютера от Artline: умный выбор для современных пользователей