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