如何对保留其初始状态的数组进行排序


How to sort array preserving its initial state

在这里使用 CakePHP 2.0。标题有点误导,所以为了澄清一下 - 我有会话数组,当用户将它们添加到购物车时,它填充了产品的 ID。所以这个数组就像 [0] => 25, [1] => 70 等。假设这个数组称为$products。

我想问的是,是否有可能使用"查找"模型的功能("条件"=> array("Product.id"=> $products))获得数组,而不是按某些 Model.field 值排序(如在"订单"选项中),而是按$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 ))

到目前为止,所有的答案都不能解决我的问题。请仔细注意我给出的示例,它非常简单,但提供的答案在不同的键中。

同样,我需要按会话数组$products的索引对最终数组$list进行排序,但是我$list按字段排序 Product.id 即使我根本没有指定任何'find(array('order'=> ...))',甚至尝试将其设置为 false。

不想听起来很粗鲁,但对我问题的所有回答都是关于如何按产品 ID 对数组进行排序(这显然不是我要求的)或关于执行手动 sql 查询的建议,这是不合适的。似乎我无法正确描述我需要什么,但我试图尽可能清楚地表达出来,对不起。

我在试图找到如何在蛋糕中"禁用订单"时偶然发现了一个解决方案。所以基本上你需要做的是有一个数组(我们称之为$queue),当你把产品ID添加到购物车时,你在其中保留产品ID,然后在查找模型函数(或分页)的"顺序"选项中,你应该提供它,比如:

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

$queue可能如下所示,例如:

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

最后,你会得到$list数组,其中产品的顺序与$queue相同。如果你没有指定"order",那么你会得到这样的数组$list

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

不出一个简单的SQL查询可以根据参数列表对结果进行排序。

因此,最简单的方法可能是在从数据库中获取记录后对记录进行重新排序。

$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);

这是有效的SQL,不确定如何使cakephp渲染它,但我认为它将解决您的订购问题:

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

我不

熟悉cake或其数据库层,但也许您可以添加一点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);

我通常处理此类问题的方式是使用 Set 类按产品 ID 索引$list,该类内置于 Cake 中。所以

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

然后使用循环浏览您的购物车 ($products),它已经按照您想要的顺序排列

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

希望这有帮助。

如果我

理解正确,您需要对模型结果进行排序,或者换句话说,对查询设置顺序以任意方式排序。

这里有两个选项:

  1. 指定排序。不熟悉 Cake,但您需要生成的 mysql 是:order by id = 25 desc, id = 70 desc, id = etc(猜测会说尝试order => 'id = 25 desc, id = 70 desc, id = etc'),您必须从$products数组中组装

  2. 创建一个购物篮模型并使用联接查询以正确的顺序获取产品列表(不简单,但可能比依赖会话变量更好)。

更新

我已经注意并确实解决了您的问题,为您提供了您需要生成的 SQL,以及对 Cake 语法的猜测。查看您发布的解决方案,您的 FIELD(id, x, x, x) 正在做同样的事情,但是一个更干净的解决方案。找到它做得很好,我会删除您的"不要粗鲁"评论,因为它们通常看起来有点粗鲁。