Function Reference >> Variable and Type Related Extensions >> Arrays >> Array Functions

PHP数组排序详解
本文详细介绍PHP中的array_multisort函数用法,通过多个实例展示如何对单个多维数组及多个数组进行排序,包括降序、升序及多维度排序。

array_multisort

array_multisort() 可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。
array_multisort 排序的数组和之前的数组要有相同数量的元素。 换言之,排序是按字典顺序排列的。

# 使用语法
$a = [3, 4, 5, 6];
array_multisort($a, SORT_DESC, SORT_REGULAR);
# 可以将参数 array &$array1 [, mixed $array1_sort_order = SORT_ASC [, mixed $array1_sort_flags = SORT_REGULAR ]]看成一个单元,函数可以接收多个单元,并且单个单元中$array1_sort_order和$array1_sort_flags可以不填,可以互换;
var_dump($a);
// 输出:
// array(4) {
//   [0]=>int(6)
//   [1]=>int(5)
//   [2]=>int(4)
//   [3]=>int(3)
// }
$a = [3, 4, 5, 6];

# 根据官方例子
# 第一个例子
$ar1 = array(10, 100, 100, 0); // 注意$ar1和$ar2中值的对应关系
$ar2 = array(1, 3, 2, 4);
# 首先对$ar1根据SORT_ASC和SORT_REGULAR排序;
# 然后对$ar2根据$ar1排序的结果依照对应顺序进行排序;
# 如果$ar1中两个值相同,那么这两个值对应$ar2中的值再根据SORT_ASC和SORT_REGULAR排序;
array_multisort($ar1, $ar2);
var_dump($ar1, $ar2);
// 输出:
// array(4) {
//   [0]=>int(0)
//   [1]=>int(10)
//   [2]=>int(100)
//   [3]=>int(100)
// }
// array(4) {
//   [0]=>int(4)
//   [1]=>int(1)
//   [2]=>int(2)
//   [3]=>int(3)
// }

# 第二个例子
$ar = array(
    array("10", 11, 100, 100, "a"),
    array(   1,  2, "2",   3,   1)
);
# 对$ar[0]按照SORT_STRING字符串比较排序,SORT_ASC正序排列;
# 对$ar[1]按照$ar[0]排序的结果依照对应顺序进行排序;
# $ar[0]中相同值对应$ar[1]里面的值按照SORT_NUMERIC数字比较顺序,SORT_DESC逆序排列
array_multisort($ar[0], SORT_ASC, SORT_STRING,
    $ar[1], SORT_NUMERIC, SORT_DESC);
var_dump($ar);
// 输出:
// array(2) {
//      [0]=> array(5) {
//          [0]=>string(2) "10"
//          [1]=>int(100)
//          [2]=>int(100)
//          [3]=>int(11)
//          [4]=>string(1) "a"
//      }
//      [1]=>array(5) {
//          [0]=>int(1)
//          [1]=>int(3)
//          [2]=>string(1) "2"
//          [3]=>int(2)
//          [4]=>int(1)
//      }
// }
# 第二个例子中如果增加一个数组
$ar = array(
    array(1, 2, 5, 5, 5, 5),
    array(11, 12, 12, 12, 12, 16),
    array(21, 22, 23, 24, 25, 26),
);
array_multisort($ar[0], SORT_DESC, SORT_STRING,
    $ar[1], SORT_NUMERIC, SORT_ASC, $ar[2], SORT_ASC);
var_dump($ar);
array_multisort($ar[0], SORT_DESC, SORT_STRING,
    $ar[1], SORT_NUMERIC, SORT_ASC, $ar[2], SORT_DESC);
var_dump($ar);
// 可以实验下以上两种输入有和不同;其实试验了这个基本就知道了array_multisort的作用方式;
// 和mysql的order by相同;
// 对三个数组进行排序的时候,第一个数组是第一个排序的字段,然后依次排序;
// 三个参数的array_multisort可以理解如下:
//  $ar[0]	$ar[1] $ar[2]
//  1       11      21
//  2       12      22
//  5       12      23
//  5       12      24
//  5       12      25
//  5       16      26
// array_multisort($ar[0], SORT_DESC, SORT_STRING, $ar[1], SORT_NUMERIC, SORT_ASC, $ar[2], SORT_ASC)
// 以上函数排序的作用效果就等同:
// order by $ar[0] desc, order by $ar[1] asc, order by $ar[2] desc
// 所以排序结果为下:
//  $ar[0]	$ar[1] $ar[2]
//  5       12      23
//  5       12      24
//  5       12      25
//  5       16      26
//  2       12      22
//  1       11      21
// array_multisort($ar[0], SORT_DESC, SORT_STRING, $ar[1], SORT_NUMERIC, SORT_ASC, $ar[2], SORT_DESC)
// 以上函数排序的作用效果就等同:
// order by $ar[0] desc, order by $ar[1] asc, order by $ar[2] desc
// 所以排序结果为下:
//  $ar[0]	$ar[1] $ar[2]
//  5       12      25
//  5       12      24
//  5       12      23
//  5       16      26
//  2       12      22
//  1       11      21

# 第三个例子
$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);
// 取得列的列表
foreach ($data as $key => $row) {
    $volume[$key]  = $row['volume'];
    $edition[$key] = $row['edition'];
}
// 将数据根据 volume 降序排列,根据 edition 升序排列
// 把 $data 作为最后一个参数,以通用键排序
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
print_r($data);
// 输出:
// array(6) {
//  [0]=>array(2) {
//      ["volume"]=>int(98)
//      ["edition"]=>int(2)
//  }
//  [1]=>array(2) {
//      ["volume"]=>int(86)
//      ["edition"]=>int(1)
//  }
//  [2]=>array(2) {
//      ["volume"]=>int(86)
//      ["edition"]=>int(6)
//  }
//  [3]=>array(2) {
//      ["volume"]=>int(85)
//      ["edition"]=>int(6)
//  }
//  [4]=>array(2) {
//      ["volume"]=>int(67)
//      ["edition"]=>int(2)
//  }
//  [5]=>array(2) {
//      ["volume"]=>int(67)
//      ["edition"]=>int(7)
//  }
// }
# 第三个例子可能比较不容易理解,再多点例子来辅助
# 例子3-1
$a = [
    ['key1' => 1, 'key2' => 10],
    ['key1' => 3, 'key2' => 11],
    ['key1' => 3, 'key2' => 12],
    ['key1' => 5, 'key2' => 13],
    ['key1' => 6, 'key2' => 14],
];
$b = [6, 5, 4, 3, 2];
array_multisort($b, $a);
var_dump($b, $a);
// 输出:
// array(5) {
//  [0]=>int(2)
//  [1]=>int(3)
//  [2]=>int(4)
//  [3]=>int(5)
//  [4]=>int(6)
// }
// array(5) {
//  [0]=>array(2) {
//      ["key1"]=>int(6)
//      ["key2"]=>int(14)
//  }
//  [1]=>array(2) {
//      ["key1"]=>int(5)
//      ["key2"]=>int(13)
//  }
//  [2]=>array(2) {
//      ["key1"]=>int(3)
//      ["key2"]=>int(12)
//  }
//  [3]=>array(2) {
//      ["key1"]=>int(3)
//      ["key2"]=>int(11)
//  }
//  [4]=>array(2) {
//      ["key1"]=>int(1)
//      ["key2"]=>int(10)
//  }
// }
# 例子3-2
$a = [
    ['key1' => 1, 'key2' => 10],
    ['key1' => 3, 'key2' => 11],
    ['key1' => 3, 'key2' => 12],
    ['key1' => 5, 'key2' => 13],
    ['key1' => 6, 'key2' => 14],
];
$b = [6, 5, 4, 3, 2];
$aKey1 = array_column($a, 'key1');
$aKey2 = array_column($a, 'key2');
array_multisort($b, $aKey1, $aKey2);
$aNew = array_map(function($v1, $v2){
    return ['key1' => $v1, 'key2' => $v2];
}, $aKey1, $aKey2);
var_dump($b, $aKey1, $aKey2, $aNew);
// 输出:
// array(5) {
//  [0]=>int(2)
//  [1]=>int(3)
//  [2]=>int(4)
//  [3]=>int(5)
//  [4]=>int(6)
// }
// array(5) {
//  [0]=>int(6)
//  [1]=>int(5)
//  [2]=>int(3)
//  [3]=>int(3)
//  [4]=>int(1)
// }
// array(5) {
//  [0]=>int(14)
//  [1]=>int(13)
//  [2]=>int(12)
//  [3]=>int(11)
//  [4]=>int(10)
// }
// array(5) {
//  [0]=>array(2) {
//      ["key1"]=>int(6)
//      ["key2"]=>int(14)
//  }
//  [1]=>array(2) {
//      ["key1"]=>int(5)
//      ["key2"]=>int(13)
//  }
//  [2]=>array(2) {
//      ["key1"]=>int(3)
//      ["key2"]=>int(12)
//  }
//  [3]=>array(2) {
//      ["key1"]=>int(3)
//      ["key2"]=>int(11)
//  }
//  [4]=>array(2) {
//      ["key1"]=>int(1)
//      ["key2"]=>int(10)
//  }
// }
# 例子3-1和3-2中,都是对$a根据$b的顺序去排序;
# 例子3-1中$a和3-2中$aNew结果一样;
# 二维数组,可以认为,二维数组被分两个一维数组,然后对这两个一维数组排序,最后再组合成一个二维数组;
# 那么现在我们可以得知官方第三个例子中,将二维数组取出他的两个一维数组,然后将二维数组按照它自己的两个一维数组的排序规则去排序;

封装过的二维数组排序方法:https://blog.youkuaiyun.com/alexander_phper/article/details/55215825
即是官方评论里面的第一条;

<think>我们正在讨论的Maven错误是关于在构建Maven插件时,maven-plugin-plugin无法自动计算goalPrefix而要求显式指定的问题。用户现在想了解在POM中配置`<extensions>true</extensions>`的作用及其与这个错误的关系。 首先,需要明确:配置`<extensions>true</extensions>`与解决这个错误没有直接关系。因为: 1. `<extensions>true</extensions>`通常用于启用Maven的核心扩展(例如,用于自定义包装类型或仓库类型),它并不影响maven-plugin-plugin如何计算goalPrefix。 2. 这个错误的原因在于maven-plugin-plugin无法从插件artifactId推导出goalPrefix,所以必须显式指定。 但是,我们可以详细解释`<extensions>`的作用,并说明它可能出现在什么场景下,以帮助用户理解。 以下是完整回答: ### 配置`<extensions>true</extensions>`的作用 在Maven插件配置中,`<extensions>`元素用于指示Maven是否加载该插件提供的扩展(extensions)。扩展是Maven的核心扩展机制,允许插件: - 提供新的打包类型(packaging) - 提供新的仓库类型(repository) - 扩展Maven核心功能(如自定义生命周期) #### 典型应用场景 ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <extensions>true</extensions> <!-- 启用扩展 --> </plugin> ``` 1. **启用自定义打包类型** 当插件定义了新的打包类型(如`maven-assembly-plugin`支持`pom`、`jar`以外的类型),需设置`<extensions>true</extensions>`激活该类型[^2]。 2. **扩展Maven核心行为** 例如`maven-shade-plugin`可通过扩展重写依赖解析逻辑(通常较少使用)。 ### 与`goalPrefix`错误的关系 **直接结论**: 配置`<extensions>true</extensions>`**无法解决**`goalPrefix`计算失败的错误。二者属于不同维度的配置: - `goalPrefix`错误源自插件元数据生成失败(`maven-plugin-plugin`执行`descriptor`目标时) - `<extensions>`用于控制插件是否作为核心扩展加载 ### 正确解决方案 回到原始错误,唯一可靠的方法是**显式指定`goalPrefix`**(如之前回答): ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.13.1</version> <configuration> <goalPrefix>custom</goalPrefix> <!-- 手动指定前缀 --> </configuration> </plugin> </plugins> </build> ``` ### 补充说明 若在插件项目中意外配置了`<extensions>true</extensions>`(通常不需要),可能导致不可预见的副作用: - 错误地尝试将插件作为扩展加载,可能干扰Maven核心 - 与`goalPrefix`错误无关,但建议移除无用配置 §§相关问题§§ 1. Maven核心扩展(extensions)和普通插件(plugins)有什么区别? 2. 如何为自定义打包类型开发Maven扩展? 3. 在哪些场景下需要避免使用`<extensions>true</extensions>`? 4. 如何验证Maven扩展是否生效? 引用说明: [^1]: 用户在引用[1]中提供了原始错误信息,明确了错误类型。 [^2]: 用户在引用[2]中给出了一段插件配置,其中未使用`<extensions>`,但该配置展示了插件执行(execution)的绑定方式,与当前话题无直接关联,故未在回答中引用。 </think>### 配置 `<extensions>true</extensions>` 的作用及与报错的关联 #### 1. **`<extensions>` 的核心作用** 在 Maven 插件配置中,`<extensions>true</extensions>` **用于启用插件的核心扩展功能**: ```xml <plugin> <groupId>com.example</groupId> <artifactId>your-plugin</artifactId> <version>1.0.0</version> <extensions>true</extensions> <!-- 关键配置 --> </plugin> ``` - **扩展机制**:允许插件修改 Maven 核心行为(如自定义生命周期、包装类型或依赖解析规则)[^2] - **生效时机**:在项目初始化阶段加载,早于常规插件执行周期 - **典型用例**: - 实现自定义打包类型(如 `war`、`zip`) - 扩展依赖管理逻辑 - 注册新的构件类型处理器 #### 2. **与 `goalPrefix` 报错的关联分析** | 配置项 | 影响范围 | 与报错的关联性 | |------------------------|----------------------------|------------------------| | **`<extensions>true`** | Maven 核心行为扩展 | ❌ 无直接关系 | | **`<goalPrefix>`** | 插件目标(Goals)标识符 | ✅ 直接解决报错的核心配置 | **关键结论**: 1. **无关性**: `goalPrefix` 报错是由于插件元数据生成失败引起的,而 `<extensions>true` 是功能扩展开关,**两者属于不同维度的配置**,添加该配置无法解决此报错[^1]。 2. **可能误用场景**: 仅当您的插件涉及以下情况时才需配置 `<extensions>true`: ```xml <!-- 正确用例:插件提供自定义打包类型 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <extensions>true</extensions> </plugin> ``` 若错误配置在普通插件上,反而可能导致: - 生命周期阶段冲突 - 构建过程异常终止 #### 3. **解决方案优先级** 正确解决 `goalPrefix` 报错的步骤: ```mermaid graph TD A[报错] --> B{检查插件命名} B -->|符合 xxx-maven-plugin 格式| C[自动推导前缀] B -->|不符合规范| D[显式配置 goalPrefix] D --> E[添加 maven-plugin-plugin 配置] E --> F[解决报错] G[添加 extensions] --> X{是否核心扩展插件?} X -->|是| H[必要配置] X -->|否| I[移除配置] ``` #### 4. **验证配置有效性** ```shell # 1. 检查插件元数据生成 mvn org.apache.maven.plugins:maven-plugin-plugin:3.13.1:descriptor # 2. 验证插件调用(使用配置的goalPrefix) mvn yourPrefix:goalName ``` ### 总结建议 - **必须配置**:通过 `<goalPrefix>` 显式指定插件前缀以解决元数据生成问题[^1] - **谨慎使用**:仅在插件提供核心扩展功能时添加 `<extensions>true` - **错误配置后果**: - 无关扩展配置会污染 Maven 核心 - 可能导致构建过程出现隐式错误
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值