Как отсортировать массив, сохраняющий его начальное состояние

Использование CakePHP 2.0 здесь. Название немного вводит в заблуждение, поэтому, чтобы очистить вещи, у меня есть сеансовый массив, который заполнен идентификаторами продуктов, поскольку пользователь добавляет их в корзину. Таким образом, этот массив выглядит как [0] = > 25, [1] = > 70 и т.д. Пусть говорят, что этот массив называется $продуктами.

Я хочу спросить, есть ли какая-то возможность иметь массив, который я получаю, используя функцию 'find' model ('conditions' = > array ('Product.id' = > $products)) для сортировки не по некоторые из значений Model.field(как в опции "order" ), а индексы массивов $products, так что, когда я представляю содержимое продуктов в поле зрения, я получаю все эти продукты в корзине, отсортированные в такой последовательности, как пользователь добавлял их.

Вот пример - Сеанс массива $products:

[0] => 35,
[1] => 15,
[2] => 25

Затем я передаю этот массив в условия функции поиска:

$list = $this->Product->find('all', array('conditions' => array('Product.id' => $products)));

В конце $list выдает массив, отсортированный по product.id. Поэтому вместо того, чтобы:

[0] => Array
    (
        [Product] => Array
            (
                [id] => 35 )),
[1] => Array
        (
            [Product] => Array
                (
                    [id] => 15 )),

[2] => Array
        (
            [Product] => Array
                (
                    [id] => 25 ))

Я получаю:

[0] => Array
    (
        [Product] => Array
            (
                [id] => 15 )),
[1] => Array
        (
            [Product] => Array
                (
                    [id] => 25 )),
[2] => Array
        (
            [Product] => Array
                (
                    [id] => 35 ))

Пока все ответы не решают мою проблему. Пожалуйста, обратите пристальное внимание на пример, который я дал, это очень просто, но ответы предоставляются в разных ключах.

Опять же, мне нужен конечный массив $list для сортировки по индексам массива сеанса $products, но я получаю $list, отсортированный по Product.id, хотя я вообще не указывал 'find(array('order'=> ...))' и даже пытался установить его в false.

Ответ 1

Не хочу звучать грубо, но все ответы на мой вопрос касались того, как упорядочить мой массив по идентификатору продукта (что явно не то, что я просил), или предложения по выполнению ручных запросов sql, что неуместно. Похоже, я не мог правильно описать, что мне нужно, но я попытался сделать это как можно более ясным, извините.

Я наткнулся на решение, пытаясь найти способ "отключить порядок" в торте. Таким образом, в основном вам нужно иметь массив (пусть он называет его $queue), где вы сохраняете идентификаторы продуктов по мере их добавления в корзину, а затем в опции "order" в режиме поиска модели ( или paginate) вы должны предоставить его как:

'order'=>array('FIELD(Product.id,'.implode(',', $queue).')')

$queue может выглядеть следующим образом:

[queue] => Array
        (
            [0] => 51
            [1] => 1
            [2] => 11
        )

В итоге вы получаете массив $list, в котором порядок продуктов такой же, как в $queue. Если вы не указали "заказ", вы получили бы массив $list следующим образом:

 [queue] => Array
            (
                [0] => 1
                [1] => 11
                [2] => 51
            )

Ответ 2

Я не могу представить простой SQL-запрос, который бы упорядочил результаты в соответствии со списком параметров.

Таким образом, самым простым, возможно, является изменение порядка записей после их получения из db.

$records = $this->Product->find('all', array('conditions' => array('Product.id' => $products)));

$sorted_records = array();
foreach($records as $record)
{
  $key = array_search($record['Product']['id'], $products);
  $sorted_records[$key] = $record;
}

ksort($sorted_records);

debug($sorted_records);

Ответ 3

Это действительный SQL, не уверен, как сделать cakephp рендерингом, но я думаю, что он решит вашу проблему заказа:

SELECT * FROM product WHERE id IN (35, 15, 25) ORDER BY id = 35 DESC, id = 15 DESC, id = 25

Ответ 4

Если я правильно понял, вам нужно заказать результат модели, или, другими словами, установить порядок запроса для сортировки произвольным образом.

Здесь два варианта:

  • Укажите сортировку. Не знакомы с Cake, но mysql, который вам нужно сгенерировать, это: order by id = 25 desc, id = 70 desc, id = etc (предполагалось бы попробовать попробовать order => 'id = 25 desc, id = 70 desc, id = etc'), который вам нужно будет собрать из массива $products.

  • создайте модель корзины и используйте запрос соединения, чтобы получить список продуктов в правильном порядке (не простой, но, вероятно, лучше, чем полагаться на сеанс var).

Обновление

Я обратил внимание и исправил вашу проблему, предоставив вам SQL, который вам нужен для создания, а также предположение о синтаксисе Cake. Глядя на ваше опубликованное решение, ваше ПОЛЕ (id, x, x, x) делает то же самое, но является гораздо более чистым решением. Хорошо сделанный для его поиска, я бы удалил ваши комментарии "не значит быть грубыми", хотя они, как правило, кажутся немного грубыми.

Ответ 5

Я не знаком с тортами или его слоями базы данных, но, возможно, вы можете добавить немного sql.

Соответствующий sql будет что-то вроде

order by field(myTable.myID, 35, 15, 25)
-- or alternatively, more cross database compatible
order by case when myTable.myID = 35 then 1
              when myTable.myID = 15 then 2
              when myTable.myID = 25 then 3
         end

однако наиболее универсальным подходом было бы просто изменить порядок в php-коде.

$products = array(35,15,25);//the ordered array
$records = array_flip($products);
foreach ($list as $row) {
    $id = $row['Product']['id'];
    $records[$id] = $row;
}
print_r($records);

Ответ 6

Как обычно я обрабатываю такие проблемы, это индексирование списка $с помощью идентификатора продукта с помощью класса Set, который встроен в Cake. Так

$list = Set::combine($list, '{n}.Product.id', '{n}.Product');

Затем используйте цикл через вашу корзину ($ products), которая уже находится в том порядке, в котором вы хотите

foreach($products as $prod) echo $list[$prod]['Product']['name'];

Надеюсь, что это поможет.