uasort()? - 从银行帐户中分类帖子

时间:2011-04-12 06:54:52

标签: php

如何使用银行帐户中的某些帖子对数组进行排序?

我需要按三个字段排序:日期,金额,累计金额

date | amount | accum_amount
01-01-11 500 500 ('amount' + previous 'accum_amount' = 'accum_amount' => 500 + 0 = 500)
01-01-11 100 600 ('amount' + previous 'accum_amount' = 'accum_amount' => 100 + 500 = 600)
01-02-11 -25 575 ('amount' + previous 'accum_amount' = 'accum_amount' => -25 + 600 = 575)
01-02-11 150 725 ('amount' + previous 'accum_amount' = 'accum_amount' => 150 + 575 = 725)
01-03-11 200 925 ('amount' + previous 'accum_amount' = 'accum_amount' => 200 + 725 = 925)
01-04-11 -25 900 ('amount' + previous 'accum_amount' = 'accum_amount' => -25 + 925 = 900)

顺便说一句。日期字段是UNIX时间戳

array(
    array(
        'time' => 1200000000,
        'amount' => 500,
        'accum_amount' => 500
        ),
    array(
        'time' => 1200000000,
        'amount' => 150,
        'accum_amount' => 725
        ),
    array(
        'time' => 1200000000,
        'amount' => 100,
        'accum_amount' => 600
        ),
    array(
        'time' => 1300000000,
        'amount' => 200,
        'accum_amount' => 925
        ),
    array(
        'time' => 1300000000,
        'amount' => -25,
        'accum_amount' => 900
        ),
    array(
        'time' => 1200000000,
        'amount' => -25,
        'accum_amount' => 575
        )
    )

6 个答案:

答案 0 :(得分:1)

将数组结构更改为:

$tmp = array(
   time => array(1200000000, 1200000000, 1200000000, ...),
   amount => array(500, 150, 100, ...),
   accum_amount => array(500, 725, 600, ...),
)

然后使用array_multisort进行排序(http://php.net/manual/en/function.array-multisort.php),如:

array_multisort($tmp['time'], SORT_ASC, $tmp['amount'], SORT_DESC, $tmp['accum_amount'], SORT_ASC);

这不是很直观,但应该有效。

当然,你可以编写一个辅助函数来映射其他数组结构上的新排序顺序。

示例:

function mySort($array, $sort) {
    $tmp = array();
    foreach ($array as $row) {
        foreach ($row as $field => $value) {
            if (!isset($tmp[$field])) {
                $tmp[$field] = array();
            }

            $tmp[$field][] = $value;
        }
    }

    $params = array();
    foreach ($sort as $field => $direction) {
        $params[] = $tmp[$field];
        $params[] = $direction;
    }

    $keys = array_keys($array);
    $params[] =& $keys;

    call_user_func_array('array_multisort', $params);

    $result = array();
    foreach ($keys as $key) {
        $result[$key] = $array[$key];
    }

    return $result;
}

呼叫:

$data = mySort($data, array(
    'time' => SORT_ASC,
    'amount' => SORT_ASC,
    'accum_amount' => SORT_ASC
));

答案 1 :(得分:0)

函数usort()就是为了这个目的而做的:

usort($data, "my_sort");

function my_sort($row1, $row2) {
  if ($row1['time']<$row2['time']) return -1;
  if ($row1['time']>$row2['time']) return 1;
  if ($row1['amount']<$row2['amount']) return -1;
  if ($row1['amount']>$row2['amount']) return 1;
  if ($row1['accum_amount']<$row2['accum_amount']) return -1;
  if ($row1['accum_amount']>$row2['accum_amount']) return 1;
  return 0;
}

答案 2 :(得分:0)

你的例子并不清楚你想要什么。你没有用这种方式描述它,但是从例子看,你想要按日期增加排序,然后逐渐增加,然后增加数量(增加?)

您只需编写比较函数并将其与数组一起传递给uasort

 $comp = function($a,$b) 
         {
            if ($a['date'] != $b['date'])
                 return $a['date'] - $b['date'];
            else if ($a['accum_amount'] != $b['accum_amount']) 
                 return $a['accum_amount'] - $b['accum_amount'];
            return $a['amount'] - $b['amount'];
         }

 uasort($arr, $comp);

您可能会发现这样的功能很有帮助。当按照重要性的顺序给出一个数组来比较时,它将创建比较函数。 (所有提升,支持下降都必然会使其复杂化)

$compMakerAsc = function($l)
                {
                  return function($a, $b) use ($l)
                  {
                    foreach($l as $k)
                    {
                        if ($a[$k] != $b[$k])
                           return $a[$k] - $b[$k]; 
                           //OR return ($a[$k] > $b[$k]) ? 1 : -1; 
                    }
                    return 0;
                 }

$myComp = $compMakerAsc('date', 'accum_amount', 'amount');
$uasort($arr, $myComp);

答案 3 :(得分:0)

$key = 'accum_amount';

function sortme($a, $b)
{
    global $key;
    if ($a[$key] == $b[$key]) {
        return 0;
    }
    return ($a[$key] < $b[$key]) ? -1 : 1;
}

usort($array, "sortme");
或许这应该有所帮助。坏事,必须定义全局变量。完整代码!!!

$array = array(
    array(
        'time' => 1200000000,
        'amount' => 500,
        'accum_amount' => 500
        ),
    array(
        'time' => 1200000000,
        'amount' => 150,
        'accum_amount' => 725
        ),
    array(
        'time' => 1200000000,
        'amount' => 100,
        'accum_amount' => 600
        ),
    array(
        'time' => 1300000000,
        'amount' => 200,
        'accum_amount' => 925
        ),
    array(
        'time' => 1300000000,
        'amount' => -25,
        'accum_amount' => 900
        ),
    array(
        'time' => 1200000000,
        'amount' => -25,
        'accum_amount' => 575
        )
    );

$key = 'accum_amount';

function sortme($a, $b)
{
    global $key;
    if ($a[$key] == $b[$key]) {
        return 0;
    }
    return ($a[$key] < $b[$key]) ? -1 : 1;
}

usort($array, "sortme");

echo "<pre>";
print_r($array);
echo "</pre>";

答案 4 :(得分:0)

让我们从评论中结合这个

  

查询就像SELECT time, amount, accum_amount FROM table

一样简单

来自原始问题的这个要求:

  

我需要按三个字段排序:日期,金额,累计金额

现在,没有关于排序是否提升的要求。让我们假设提升。

SELECT time, amount, accum_amount 
  FROM table
 ORDER BY time ASC, amount ASC, accum_amount ASC

这将为我们提供按时间排序的所有数据 first 。当时间相同时,它将按数量排序,最低的第一个和最高的最后一个。当时间相同时,它将按累计金额排序第三,再次排序最低的第一个,最后一个。

使用排序更改操作的顺序就像在ORDER BY子句中更换列表一样简单。从最大到最小就像从ASC切换到DESC一样简单。

请注意,与PHP中的排序相比,此方法相对容易。只要你可以,让你的数据库给你预先排序的结果。


因为我需要离开网站几个小时,所以我打算快速输入。我现在正在假设你想重新计算累计值

我们的查询现在是:

SELECT time, amount
  FROM table
 ORDER BY time ASC, amount DESC

我们将成为友好银行并首先执行所有存款(金额增加),然后执行所有借记(金额减少),处理最后的借记,而不是较小的借记。

鉴于$data是我们的数组:

$running_total = 0;
foreach($data as $index => $row) {
    $data[$index]['accum_amount'] = $running_total + $row['amount'];
    $running_total = $data[$index]['accum_amount'];
}

根据我上面概述的业务规则,这应成功重建accum_amount列表。

答案 5 :(得分:-1)

在将数据放入db

之前,我找到了另一种方法