Сортировать массив по значению, а затем случайным образом в пределах этих значений, НО сгруппировать определенные элементы - или пересмотреть запрос MySQL, чтобы объединить все это? - PullRequest
0 голосов
/ 24 января 2012

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

Это приведет к чему-то вроде:

name: Delta 1 - total_weight: 5
name: Delta 1b - total_weight: 5
name: Charlie 12 - total_weight: 5
name: Charlie 12b - total_weight: 5
name: Charlie 12c - total_weight: 5
name: Alpha 10 - total_weight: 4
name: Delta 2 - total_weight: 3
name: Delta 2b - total_weight: 3
name: Bravo 5 - total_weight: 3

Массив перед сортировкой выглядит так:

Array
(
[463] => stdClass Object
(
    [name] => Delta 1b
    [total_weight] => 5
)
[463] => stdClass Object
(
    [name] => Charlie 12
    [total_weight] => 5
)
[340] => stdClass Object
(
    [name] => Charlie 12b
    [total_weight] => 5
)
[340] => stdClass Object
(
    [name] => Charlie 12c
    [total_weight] => 5
)
[342] => stdClass Object
(
    [name] => Delta 1
    [total_weight] => 5
)
[532] => stdClass Object
(
    [name] => Alpha 10
    [total_weight] => 4
)
[203] => stdClass Object
(
    [name] => Bravo 5
    [total_weight] => 3
)
[206] => stdClass Object
(
    [name] => Delta 2
    [total_weight] => 3
)
[208] => stdClass Object
(
    [name] => Delta 2b
    [total_weight] => 3
)

Я знаю, что для сортировки по весу, то по алфавиту я мог бы использовать usort:

function _sort_by_total_weight($a, $b)
{
    if ($a->total_weight == $b->total_weight) {
        return strcmp($a->name, $b->name);
    }
    return ($a->total_weight > $b->total_weight) ? -1 : 1;
}

Но я хочу, чтобы результаты не были в алфавитном порядке и казались случайными, но вместе с тем сгруппируйте некоторые подходящие треки. Я понимаю, что мог бы бросить строку в БД для порядка сортировки или чего-то еще, но с 10 000+ записями это нелегко реализовать. Есть мысли о том, как взломать этот орех?

EDIT : Итак, я переработал это на стороне базы данных (MySQL), чтобы запрос был взвешен и упорядочен до того, как он достигнет php:

$this->db->select('tracks.id, 
                            tracks.name AS name, 
                            tracks.filename, 
                            tracks.url_name, 
                            tracks.file_path_high, 
                            tracks.filesize, 
                            tracks.categories,
                            tracks.duration, 
                            tracks.folder,
                            links.tag_id,
                            SUM(links.weight) AS total_weight,
                            tag_data.tag_name');

        $this->db->distinct();
        $this->db->from('music AS tracks');
        $this->db->where_in('links.tag_id', array('1', '2');
        $this->db->join('linked_tags AS links', 'links.track_id = tracks.id', 'inner');
        $this->db->join('tags AS tag_data', 'tag_data.id = links.tag_id', 'inner');
        $this->db->group_by("name", "total_weight");
        $this->db->order_by('total_weight DESC, RAND(123)'); 
        $this->db->limit($total, $offset);

Но теперь у меня есть несколько почти одинаковых записей в результате. Для where_in есть ли способ заявить, что я хочу только записи, которые имеют записи как для 1, так и для 2, и не должны возвращать все записи, где 1 соответствует ИЛИ 2 соответствует?

1 Ответ

0 голосов
/ 24 января 2012

Вы можете shuffle () результаты вашего массива. Пример из PHP.net:

<?php
   $numbers = range(1, 20);
   shuffle($numbers);
   foreach ($numbers as $number) {
      echo "$number ";
   }
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...