对二维数组进行二次排序的方法

很多时候,我们需要对一个二维关联数组进行排序,而且这种排序可能不是一次就能排好,打个比方,一份成绩单,首先按照分数倒序排序,在分数相同的情况下,按照学号进行顺序排列;

代码

<?php 

uasort($arr, 'my_sort');

function my_sort($a, $b) {

    // 全局化排序键
    global $firstKey, $secondKey;

    // 如果第一排序键对应的值相同
    if (intval($a[$firstKey]) == intval($b[$firstKey])) {
        // 则按第二排序键进行顺序排列
        return (intval($a[$secondKey]) > intval($b[$secondKey])) ? 1 : -1;
    } else {
        // 否则按第一排序键进行倒序排列
        return (intval($a[$firstKey]) > intval($b[$firstKey])) ? -1 : 1;
    }
}

?>

测试

$arr = array(
        array(
            'name'=>'悔创阿里杰克马',
            'score'=>'96',
            'number'=>'02',
        ),
        array(
            'name'=>'普通家庭马化腾,',
            'score'=>'96',
            'number'=>'01',
        ),
        array(
            'name'=>'不知妻美刘强东',
            'score'=>'96',
            'number'=>'03',
        ),
        array(
            'name'=>'一无所有王健林',
            'score'=>'90',
            'number'=>'05',
        ),
        array(
            'name'=>'随便挣钱丁三石',
            'score'=>'90',
            'number'=>'34',
        ),
        array(
            'name'=>'名下无房潘石屹',
            'score'=>'100',
            'number'=>'11',
        ),
        array(
            'name'=>'下周回国贾跃亭',
            'score'=>'80',
            'number'=>'06',
        ),
        
    );

// 第一排序键
$firstKey = 'score';
// 第二排序键
$secondKey = 'number';

uasort($arr, 'my_sort');

var_dump($arr);

结果

/opt/wwwroot/test/test3.php:65:
array (size=7)
  5 => 
    array (size=3)
      'name' => string '名下无房潘石屹' (length=21)
      'score' => string '100' (length=3)
      'number' => string '11' (length=2)
  1 => 
    array (size=3)
      'name' => string '普通家庭马化腾,' (length=24)
      'score' => string '96' (length=2)
      'number' => string '01' (length=2)
  0 => 
    array (size=3)
      'name' => string '悔创阿里杰克马' (length=21)
      'score' => string '96' (length=2)
      'number' => string '02' (length=2)
  2 => 
    array (size=3)
      'name' => string '不知妻美刘强东' (length=21)
      'score' => string '96' (length=2)
      'number' => string '03' (length=2)
  3 => 
    array (size=3)
      'name' => string '一无所有王健林' (length=21)
      'score' => string '90' (length=2)
      'number' => string '05' (length=2)
  4 => 
    array (size=3)
      'name' => string '随便挣钱丁三石' (length=21)
      'score' => string '90' (length=2)
      'number' => string '34' (length=2)
  6 => 
    array (size=3)
      'name' => string '下周回国贾跃亭' (length=21)
      'score' => string '80' (length=2)
      'number' => string '06' (length=2)

 

总结

1, 对已有方法的运用掌握还不够,总想着自己造轮子,需要再强化;

2, 这个方法还的封装性还不够好,不能使用匿名函数;

 

自己写的复杂未完结待修改版本

/*
 * 二维数组排序
 * $arr 需要处理的二维数组
 * $row 需要排序的列
 * $type 倒序还是升序
 * 一次排序保留键值对对应关系,二次排序不保留键值对应关系
*/
function array_sort($arr, $firstRow, $secondRow, $type='asc') {

	$firstRowResult = array();
	$secondRowResult = array();
	
	// 先按第一排序键排列好
	if (!empty($arr)) {
		foreach ($arr as $key=>$value) {
			// 在二维数组的所有元素中第一排序键对应的所有值
			$firstRowArray[$key] = $value[$firstRow];
		}
		if ($type == 'asc') {
			asort($firstRowArray);
		} else {
			arsort($firstRowArray);
		}
		
		reset($firstRowArray);
		foreach ($firstRowArray as $k=>$v) {
			$firstRowResult[$k] = $arr[$k];
		}
	}

	// 再进行第二排序键的排列

	// 如果第一排序键对应了相同的值,则按第二排序键进行排序
	// 在第一排序键相同值数组中,用第二排序键的顺序来决定二维数组的键的排序
	// 如何取出第一排序键相同值的数组
	if ($secondRow == '') {
		return $firstRowResult;
	} else {
		print 11111111;
		var_dump($firstRowResult);
		$firstRowArray = array();
		// 取出所有值,不保留键值对关系
		// $firstRowResult = array_values($firstRowResult);
		foreach ($firstRowResult as $key=>$value) {
			// 在二维数组的所有元素中第一排序键对应的所有值
			$firstRowArray[$key] = $value[$firstRow];
		}
		var_dump($firstRowArray);
		foreach ($firstRowArray as $firstRowKey=>$firstRowValue) {
			// 第一排序键的值出现的所有键
			$firstRowSameValueKeys = array_keys($firstRowArray, $firstRowValue);
			var_dump($firstRowSameValueKeys);
			// 第一排序键的值出现的次数
			$len = count($firstRowSameValueKeys);
			// 如果第一排序键的值只出现过一次
			if ($len == 1) {
				print '跳过1';
				$secondRowResult[] = $firstRowValue;
				continue;
			// 如果出现过多次,则有重复值
			} else {
				// 重复值的键都是挨在一起的
				// 在重复值内部按第二排序键进行排序
				$secondRowArray = array();
				// 对所有拥有相同值的第一键进行遍历
				foreach ($firstRowSameValueKeys as $firstRowSameValueKey) {
					// 取出二维数组中第一键的值相同的所有元素
					$secondRowArray[$firstRowSameValueKey] = $firstRowResult[$firstRowSameValueKey];
				}
				var_dump($secondRowArray);
				// 将第一键的值相同的所有元素组成的数组按第二键进行排序,返回排序后的第一键的值相同的所有元素组成的数组
				$secondRowArray = array_sort($secondRowArray, $secondRow, '', $type);
				var_dump($secondRowArray);
				$secondRowResult = array_merge($secondRowResult, $secondRowArray);
				var_dump($secondRowResult);
			}
		}
		return $secondRowResult;
	}
	
}

$result = array_values($result);

 

转载于:https://my.oschina.net/u/3412738/blog/1600692

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值