Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php uasort()?-从银行帐户对邮件进行排序_Php - Fatal编程技术网

Php uasort()?-从银行帐户对邮件进行排序

Php uasort()?-从银行帐户对邮件进行排序,php,Php,如何从银行帐户对包含一些帖子的数组进行排序 我需要按三个字段排序:日期、金额、累计金额 即 顺便说一句,日期字段是UNIX时间戳 array( array( 'time' => 1200000000, 'amount' => 500, 'accum_amount' => 500 ), array( 'time' => 1200000000, 'amount' =

如何从银行帐户对包含一些帖子的数组进行排序

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

顺便说一句,日期字段是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
        )
    )

将阵列结构更改为类似以下内容:

$tmp = array(
   time => array(1200000000, 1200000000, 1200000000, ...),
   amount => array(500, 150, 100, ...),
   accum_amount => array(500, 725, 600, ...),
)
然后使用数组_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);
这不是很直观,但它应该可以工作

当然,您可以编写一个helper函数,将新的排序顺序映射到其他数组结构上

例如:

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;
}
电话:

功能是为此目的而设计的:

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;
}

你的例子并不清楚你想要什么。您并没有这样描述它,但从示例中可以看出,您希望按日期递增,然后累计金额递增,然后金额递增进行排序

您只需编写一个比较函数并将其与数组一起传递给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);
也许这会有所帮助。糟糕的是,必须定义全局变量。完整的代码

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

让我们结合这些评论

查询就像从表中选择时间、金额、累计金额一样简单

根据原问题的这一要求:

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

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

SELECT time, amount
  FROM table
 ORDER BY time ASC, amount DESC
这将为我们提供所有首先按时间排序的数据。当时间相同时,它将按数量进行第二次排序,最低的第一次排序,最高的最后一次排序。当时间和金额相同时,它将按累计金额进行第三次排序,再次排序最低的第一次,最高的最后一次

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

请注意,与PHP中的排序相比,此方法相对简单。只要有可能,就让数据库为您提供预排序的结果

因为我需要离开网站几个小时,所以我会很快把它打出来。我现在的操作假设是你想重新计算累计值

我们现在的问题是:

$running_total = 0;
foreach($data as $index => $row) {
    $data[$index]['accum_amount'] = $running_total + $row['amount'];
    $running_total = $data[$index]['accum_amount'];
}
我们将是一家友好的银行,首先执行所有存款金额的增加,然后执行所有借项金额的减少,最后处理最大的借项,而不是较小的借项

给定$data是我们的阵列:


考虑到我上面概述的业务规则,这将成功地重建累计金额列表。

在将数据放入数据库之前,我已经找到了另一种方法。

您是如何获取此数据的?这很重要-在实际检索时执行排序可能更容易。@用户,当然,如果它们的顺序正确,您就不需要对它们进行排序。你说划船。您正在从数据库中提取这些数据吗?关系数据库?如果是的话,你能告诉我们你使用的查询吗?查询本身可以被修改,以提供您想要的输出。@用户,也可以给自己一个比555222更友好的名字…@Charles另一方面,这里有一些严肃的数字游戏555222@clarkk:然后您可以执行以下操作:选择时间、金额、,根据您想要的订单,按时间描述或ASC累计表订单金额。我建议学习更多关于SQL的知识;我不知道这个网站有多好,但它给人留下了很好的印象:这难道不意味着时间/账户/金额彼此失去了所有关系吗?如果我错了,提供一个解决方案。如果我是。。。考虑更改您的响应。@Khez,只要原始哈希组合数组中的每个元素都有相同的键,这样将它们分开将得到大小相同的数组。新数组的索引将与旧位置相对应,$tmp['time'][41]中的数据将与$tmp['amount'][41]和$tmp['accum_amount'][41]相对应。除非所有这些值每次都出现在原始数据中,否则此方法将失败。@相反,很明显数字键将被重新索引。。所以我再次问。这是一个怎样的有效答案?@Khez,查看链接手册页面上的示例-当索引号被丢弃时,值被随机移动以对应第一个数组的排序。第一个例子说明了这一点:10/1100/31000/2,0/4变成了0/4,10/11100/2100/2,100/3。即使这样,他也不必将结构良好的数组拆分成3个并行数组。他专门要求使用uasort,所以我想原始索引对他很重要。很高兴你发布了这一点,我把我的比较函数倒过来了,直到我读了你的才意识到=P@jon_darkstar当前位置我没有看到任何ua
需要排序,也没有关于键的任何说明。最初的问题没有注意到任何可能意味着重新排序的键是受欢迎的。@Skrol29-这是标题的一部分,尽管可能没有很好的理由that@jon_darkstar当前位置我同意这并不清楚。我将把这个问题留到@Charles给出更明确的规格之前。它没有按照我想要的方式工作。。不能只在每个字段中添加asc og desc。。请再核对一下我的问题。。它更新了一个更好的版本description@clarkk那么,恐怕我不知道解决办法。不过,还原数组将为您提供DESC视图。它不能按我希望的方式工作。。不能只在每个字段中添加asc og desc。。请再核对一下我的问题。。它更新了一个更好的版本description@clarkk,我不明白你的问题现在有什么不同。我仍然在您的数据中看到相同的三个字段,并且您还没有指定如何对它们进行排序。如果不希望对列进行排序,则不要对其进行排序。请记住,如果不为每个字段指定排序方法,数据库将不会以相同的顺序一致返回相同的行,这可能会导致意外结果。金额+上一累计金额=当前累计金额_amount@clarkk,这跟我没什么关系。请问你想按什么分类?累计金额已在您的数据中…累计金额不必增加,但如果金额小于0,则可能会减少
$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>";
SELECT time, amount, accum_amount 
  FROM table
 ORDER BY time ASC, amount ASC, accum_amount ASC
SELECT time, amount
  FROM table
 ORDER BY time ASC, amount DESC
$running_total = 0;
foreach($data as $index => $row) {
    $data[$index]['accum_amount'] = $running_total + $row['amount'];
    $running_total = $data[$index]['accum_amount'];
}