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

10

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

我的问题是,是否有可能通过使用“find”模型函数('conditions' => array('Product.id' => $products))获取的数组按照$products数组的索引排序,而不是按Model.field值进行排序(如'order'选项),这样当我在视图中呈现产品内容时,我可以获得以用户添加它们的顺序排序的所有那些在购物车中的产品。

这里有一个例子 - Session数组 $products:

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

然后我将这个数组传递给find函数的条件:

$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。


3
我猜您无法理解问题,但是这个建议或许可以帮到您……当您排序一个数组时,无法保持其原始状态(因为您正在进行排序)。但是您可以将其存储两次,甚至更好的方法是,您可以在初始状态下存储数组的索引,这样您就可以随时按照初始状态对数组进行排序(或反过来)。$initial_state_indexes = array_keys($the_array); - Packet Tracer
同意,问题有点含糊不清... 请尝试用代码澄清您的观点或从不同角度来解释。 - mseancole
我根本没有使用“order”。正如我所说,会话数组$products包含产品的ID,其中索引(从[0]开始)表示用户添加的产品序列。 - kK-Storm
我不确定你为什么提到了“order”,没有其他人提到过它。“(例如' order '选项)”,“这样当我呈现订单内容时”。 - mseancole
2
我一直在关注,正如我所说,你的原始帖子非常模糊。我回复时是根据我看到的来说明我发现它有多么模糊。现在你已经添加了我建议的更改,你得到了4个答案和我的最后一条评论作为潜在解决方案,比你原本会得到的要多。没有必要无礼。你尝试过任何提供的解决方案吗,还是只是回去争论一个无用的观点? - mseancole
显示剩余4条评论
6个回答

2
不想听起来粗鲁,但所有对我的问题的回答都是关于如何按产品ID排序我的数组(这显然不是我要求的),或者建议进行手动SQL查询,这是不合适的。看起来我无法正确描述我需要什么,但我尽可能清楚地说明了,抱歉。
在寻找如何在蛋糕中“禁用订单”时,我偶然发现了一个解决方案。所以基本上你需要做的是有一个数组(让我们称其为$queue),在添加到购物车时保留产品ID,然后在find模型函数(或分页)中的“order”选项中提供它,例如:
'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
            )

0
这是有效的SQL语句,不确定如何使cakephp渲染它,但我觉得它可以解决你的排序问题:
SELECT * FROM product WHERE id IN (35, 15, 25) ORDER BY id = 35 DESC, id = 15 DESC, id = 25

0

如果我理解正确,您需要对模型结果进行排序,或者换句话说,在查询中设置一个任意的排序方式。

这里有两个选项:

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

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

更新

我注意到并修复了您的问题,为您提供了所需的 SQL,以及 Cake 语法的猜测。看着您发布的解决方案,您的 FIELD(id, x, x, x) 做了同样的事情,但是是一个更干净的解决方案。找到它很好,我会删除您的“不想无礼”的评论,因为它们通常看起来有点无礼。


0

我想不出一个简单的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);

0

我不熟悉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);

0
通常我处理这类问题的方式是使用Set类,该类已经内置在Cake中,通过将$list按照产品ID进行索引。
$list = Set::combine($list, '{n}.Product.id', '{n}.Product');

然后通过循环遍历您的购物车($products),它已经按照您想要的顺序排列。

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

希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接