Почему из-за array_merge некорректно работает usort

226
11 апреля 2018, 07:47

Предо мной стоит следующая задача: выводить 4 новости в блоке, отсортированные по году по возрастанию. Я делаю это так:

//ищем в news и ThisDay и сливаем два массива вместе
$mergedArray = array_merge(
    //выборка из таблицы thisDay
    ThisDay::find() - > where(
        new Expression(
            "day = :dateDay"
            .
            " AND id_region = :id_region"
            .
            " AND month = :month", [":dateDay" => $dateDay,
                ":month" => $currentMoth,
                ":id_region" => REGION_ID
            ])) - > orderBy("news_date DESC") - > all(),
    //поиск по таблице News с лимитом 4 - (минус) кол-во новостей в ThisDay
    News::find() - > alias("n") - > select() - > 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());

а потом сортирую переиндексированный по годам массив (переиндексирую для того чтобы может быть его по ключам отсортировать, но все равно ничего не выходит, потому что вы итоге ключи все равно 0, 1, 2, 3) Переиндексирую вот так:

 //индексирую, если ThisDay
$indexedThisDay = ArrayHelper::index($mergedArray, function($element) {
    if ($element instanceof ThisDay) {
        return (int)\ Yii::$app - > formatter - > asDate($element['news_date'], 'yyyy');
        //                        return $element['news_date'];
    }
});
//индексирую, если News
$indexedNews = ArrayHelper::index($mergedArray, function($element) {
    if ($element instanceof News) {
        return (int)\ Yii::$app - > formatter - > asDate($element['cdate_int'], 'yyyy');
        //                        return $element['cdate_int'];
    }
});
//        мержу проиндексированные массивы
$model = array_merge($indexedNews, $indexedThisDay);
//здесь вызываю функцию сортировки 
$this->sortBy($model);

Получаю массив из двух элементов внутри которых другие массивы, по умолчанию они не отсортированы никак, я делаю сортировку usort следующим образом:

    function sortBy($array) {
    usort($array, function($item1, $item2) {
        if ($item1 instanceof News) {
            if ($item1['cdate_int']) {
                $newsArr = $item1['cdate_int'];
            }
        }
        if ($item2 instanceof ThisDay) {
            if ($item2['news_date']) {
                $thisDayArr = $item2['news_date'];
            }
        }
        if ($thisDayArr == $newsArr)
            return 0;
        return ($thisDayArr < $newsArr) ? -1 : 1;
    });
    return true;
}

Эта сортировка работает только на 50% так как она сортирует каждый из двух массивов отдельно, что дает в итоге массив в порядке 2017, 2016, 2017, 2016, тогда как должно быть 2017, 2017, 2016, 2016.

Я не знаю как сделать лучше и какие ошибки в моем решении, буду рад и советам как можно сделать это лучше и помощи с кодом для выборки, сортировки или смерживания (не знаю точно в чем проблема)

READ ALSO
jquery через on не видит данные загруженные через ajax

jquery через on не видит данные загруженные через ajax

Добрый день, загружаю форму через ajax, навешиваю к примеру на input id='test'

165
Яндекс Карты и подгруженный контент по аяксу

Яндекс Карты и подгруженный контент по аяксу

На сайте есть контент, которые обновляется по фильтрам (выбрал чекбокс - перезагрузка контента по аяксу)В контенте есть ссылки на попап-карты

224