AutoJs6

- Overview - 综述
- About - 关于文档
- Progress - 文档部署进度
- Changelog - 文档更新日志

- Manual - AutoJs6 使用手册
- Q & A - 疑难解答

- Global - 全局对象
- Automator - 自动化
- AutoJs6 - 本体应用
- App - 通用应用
- Color - 颜色
- Image - 图像
- OCR - 光学字符识别
- Barcode - 条码
- QR Code - 二维码
- Keys - 按键
- Device - 设备
- Storage - 储存
- File - 文件
- Engine - 引擎
- Task - 任务
- Module - 模块
- Plugins - 插件
- Toast - 消息浮动框
- Notice - 消息通知
- Console - 控制台
- Shell
- Shizuku
- Media - 多媒体
- Sensor - 传感器
- Recorder - 记录器
- Timer - 定时器
- Thread - 线程
- Continuation - 协程
- Event - 事件监听
- Dialog - 对话框
- Floaty - 悬浮窗
- Canvas - 画布
- UI - 用户界面
- Web - 万维网
- HTTP
- Base64
- Crypto - 密文
- Internationalization - 国际化
- Standardization - 标准化
- E4X

- UiSelector - 选择器
- UiObject - 控件节点
- UiObjectCollection - 控件集合
- UiObjectActions - 控件节点行为
- WebSocket
- EventEmitter - 事件发射器
- ImageWrapper - 包装图像类
- App - 应用枚举类
- Color - 颜色类
- Version - 版本工具类
- Polyfill - 代码填泥
- Arrayx - Array 扩展
- Numberx - Number 扩展
- Mathx - Math 扩展

- Exceptions - 异常
- Intent - 意图
- Runtime - 运行时
- Context - 上下文
- Activity - 活动

- Scripting Java - 脚本化 Java
- Android API Level - 安卓 API 级别
- Color Table - 颜色列表

- Glossaries - 术语
- HttpHeader - HTTP 标头
- HttpRequestMethods - HTTP 请求方法
- MimeType - MIME 类型
- NotificationChannel - 通知渠道

- Data Types - 数据类型
- Omnipotent Types - 全能类型
- Storage - 存储类
- AndroidBundle
- AndroidRect
- CryptoCipherOptions
- CryptoKey
- CryptoKeyPair
- ConsoleBuildOptions
- HttpRequestBuilderOptions
- HttpRequestHeaders
- HttpResponseBody
- HttpResponseHeaders
- HttpResponse
- InjectableWebClient
- InjectableWebView
- NoticeOptions
- NoticeChannelOptions
- NoticePresetConfiguration
- NoticeBuilder
- Okhttp3HttpUrl
- OcrOptions
- Okhttp3Request
- OpencvPoint
- OpencvRect
- OpencvSize

- GitHub - 应用项目地址
- GitHub - 文档项目地址

# Arrayx (Array 扩展)#

Arrayx 用于扩展 JavaScript 标准内置对象 Array 的功能 (参阅 内置对象扩展).

Arrayx 全局可用:

    console.log(typeof Arrayx); // "object"
    console.log(typeof Arrayx.union); // "function"

当启用内置扩展后, Arrayx 将被应用在 Array 及其原型上:

    console.log(typeof Array.prototype.union); // "function"
    console.log(typeof [].union); // "function"

## 启用内置扩展#

内置扩展默认被禁用, 以下任一方式可启用内置扩展:

- 在脚本中加入代码片段: `plugins.extendAll();` 或 `plugins.extend('Array');`
- AutoJs6 应用设置 - 扩展性 - JavaScript 内置对象扩展 - [ 启用 ]

当上述应用设置启用时, 所有脚本均默认启用内置扩展.
当上述应用设置禁用时, 只有加入上述代码片段的脚本才会启用内置扩展.
内置扩展往往是不安全的, 除非明确了解内置扩展的原理及风险, 否则不建议启用.

## 排序稳定性#

Arrayx 的诸多排序方法, 如 [ sortBy / sortDescending / sortByDescending / sorted / sortedBy / sortedDescending / sortedByDescending ] 等, 其内部实现均调用了 JavaScript 的原生方法 Array.prototype.sort.

自 ES10 (ECMAScript 2019) 起, 规范 要求 Array.prototype.sort 为稳定排序, 因此 Arrayx 的排序方法也是稳定的.

> 参阅: MDN

## 排序方式#

Arrayx 排序方法中的 selector (条件选择器) 使用的 compareFn (比较函数) 与默认的稍有不同.
默认的比较函数按照转换为字符串的诸个字符的 Unicode 位点进行 升序 排序, 例如 80 会被排列到 9 之前.
而 Arrayx 排序方法的 selector 则采用简单的直接比较方法:

    /* Arrayx 使用的 compareFn. */
    (a, b) => a === b ? 0 : a > b ? 1 : -1;

因此对于 number 数组的排序会出现不同的结果:

    console.log([ 80, 70, 9 ].sort()); // [ 70, 80, 9 ]
    console.log(Arrayx.sorted([ 80, 70, 9 ])); // [ 9, 70, 80 ]

Arrayx

## [m] ensureArray#

### ensureArray(...o)#

`6.2.0` `xObject`

- o { ...any[] } - 任意对象
- returns { void }

相当于严格类型检查, 当任意一个 o 不满足 `Array.isArray(o)` 时抛出异常.

    /* 确保每一个对象都是 Array. */

    console.log(Arrayx.ensureArray([])); /* 无异常. */
    console.log(Arrayx.ensureArray([], 9)); /* 抛出异常. */
    console.log(Arrayx.ensureArray([ 5 ], [ 2, 3 ])); /* 无异常. */

    /* 启用内置对象扩展后. */

    console.log(Array.ensureArray([])); /* 无异常. */
    console.log(Array.ensureArray([], 9)); /* 抛出异常. */
    console.log(Array.ensureArray([ 5 ], [ 2, 3 ])); /* 无异常. */

## [m] intersect#

### intersect(o, ...others)#

`6.2.0` `xProto`

- o { T[] } - 数组
- others { ...U[][] } - 待处理数组
- returns { (T & U)[] }

返回多个数组的交集.

    let arrA = [ 1, 2, 3 ];
    let arrB = [ 2, 3, 4 ];
    console.log(Arrayx.intersect(arrA, arrB)); // [ 2, 3 ]

    /* 启用内置对象扩展后. */
    console.log(arrA.intersect(arrB)); /* 同上. */

    let arrC = [ 1, 1, 2 ];
    let arrD = [ 1, 1, 3 ];
    /* 返回的交集结果中不包含重复元素. */
    console.log(Arrayx.intersect(arrC, arrD)); // [ 1 ]

    /* 启用内置对象扩展后. */
    console.log(arrC.intersect(arrD)); /* 同上. */

## [m] union#

### union(o, ...others)#

`6.2.0` `xProto`

- o { T[] } - 数组
- others { ...U[][] } - 待处理数组
- returns { (T | U)[] }

返回多个数组的并集.

    let arrA = [ 1, 2 ];
    let arrB = [ 3, 4 ];
    console.log(Arrayx.union(arrA, arrB)); // [ 1, 2, 3, 4 ]

    /* 启用内置对象扩展后. */
    console.log(arrA.union(arrB)); /* 同上. */

    let arrC = [ 7, 8, 9 ];
    let arrD = [ 7, 10 ];
    /* 返回的并集结果中不包含重复元素. */
    console.log(Arrayx.union(arrC, arrD)); // [ 7, 8, 9, 10 ]

    /* 启用内置对象扩展后. */
    console.log(arrC.union(arrD)); /* 同上. */

## [m] distinct#

### distinct(arr)#

`6.2.0` `xProto`

- o { T[] } - 待处理数组
- returns { T[] }

返回去除重复元素后的新数组.

    let arr = [ 1, 2, 1, 3, 2, 2 ];
    console.log(Arrayx.distinct(arr)); // [ 1, 2, 3 ]

    /* 启用内置对象扩展后. */
    console.log(arr.distinct()); /* 同上. */

## [m] distinctBy#

### distinctBy(arr, selector)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- selector { (e: T) => U } - 条件选择器
- returns { T[] }

返回按一定条件去除重复元素后的新数组.

    /* 按奇偶条件去重. */
    /* 即结果数组中的所有元素保证相互之间奇偶互异. */
    let arrA = [ 1, 2, 1, 3, 2, 2 ];
    console.log(Arrayx.distinctBy(arrA, e => e % 2)); // [ 1, 2 ]

    /* 启用内置对象扩展后. */
    console.log(arrA.distinctBy(e => e % 2)); // /* 同上. */

    /* 按字符串长度条件去重. */
    /* 即结果数组中的所有元素保证相互之间长度不同. */
    let arrB = [ 'a', 'ab', 'c', 'bc', 'abc', '123' ];
    console.log(Arrayx.distinctBy(arrB, e => e.length)); // [ 'a', 'ab', 'abc' ]

    /* 启用内置对象扩展后. */
    console.log(arrB.distinctBy(e => e.length)); /* 同上. */

    /* 按对象属性条件去重. */
    let arrC = [
        { num: 1, count: 10 },
        { num: 2, count: 10 },
        { num: 3, count: 20 },
        { num: 4, count: 10 },
        { num: 5, count: 20 },
    ];
    console.log(Arrayx.distinctBy(arrC, e => e.count)); // [ { num: 1, count: 10 }, { num: 3, count: 20 } ]

    /* 启用内置对象扩展后. */
    console.log(arrC.distinctBy(e => e.count)); /* 同上. */

## [m] sortBy#

### sortBy(arr, selector)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- selector { (e: T) => U } - 条件选择器
- returns { T[] }

按一定条件原地排序, 并返回排序后的新数组.
方法调用后, 原数组将发生改变.

    /* 将字符串按 "数字化" 顺序排序. */
    let arrA = [ '10', '2', '30', '4', '50', '0x6' ];
    console.log(Arrayx.sortBy(arrA, Number)); // [ '2', '4', '0x6', '10', '30', '50' ]

    /* arrA 将发生改变. */
    console.log(arrA); // [ '2', '4', '0x6', '10', '30', '50' ]

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrA.sortBy(Number)); /* 结果同上. */

    /* 按字符串长度条件排序. */
    let arrB = [ 'a', 'ab', 'c', 'bc', 'abc', '123' ];
    console.log(Arrayx.sortBy(arrB, e => e.length)); // [ 'a', 'c', 'ab', 'bc', 'abc', '123' ]

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrB.sortBy(e => e.length)); /* 结果同上. */

    /* 按对象属性条件排序. */
    let arrC = [
        { num: 1, count: 10 },
        { num: 2, count: 30 },
        { num: 3, count: 20 },
        { num: 4, count: 10 },
        { num: 5, count: 0 },
    ];
    console.log(Arrayx.sortBy(arrC, e => e.count)); /* num 按照 5 - 1 - 4 - 3 - 2 排序. */

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrC.sortBy(e => e.count)); /* 结果同上. */

## [m] sortDescending#

### sortDescending(arr)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- returns { T[] }

按一定条件原地 降序 排序, 并返回排序后的新数组.
方法调用后, 原数组将发生改变.

    /* 将字符串按 "数字化" 顺序排序. */
    let arrA = [ '10', '2', '30', '4', '50', '0x6' ];

    // [ '2', '4', '0x6', '10', '30', '50' ]
    console.log(Arrayx.sortDescending(arrA, Number));

    /* arrA 将发生改变. */
    console.log(arrA[0]); // '2'

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrA.sortDescending(Number)); /* 结果同上. */

    /* 按字符串长度条件排序. */
    let arrB = [ 'a', 'ab', 'c', 'bc', 'abc', '123' ];

    // [ 'a', 'c', 'ab', 'bc', 'abc', '123' ]
    console.log(Arrayx.sortDescending(arrB, e => e.length));

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrB.sortDescending(e => e.length)); /* 结果同上. */

    /* 按对象属性条件排序. */
    let arrC = [
        { num: 1, count: 10 },
        { num: 2, count: 30 },
        { num: 3, count: 20 },
        { num: 4, count: 10 },
        { num: 5, count: 0 },
    ];

    /* 元素将按照 num 属性值以 5 - 1 - 4 - 3 - 2 排序. */
    console.log(Arrayx.sortDescending(arrC, e => e.count));

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrC.sortDescending(e => e.count)); /* 结果同上. */

## [m] sortByDescending#

### sortByDescending(arr, selector)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- selector { (e: T) => U } - 条件选择器
- returns { T[] }

按一定条件原地 降序 排序, 并返回排序后的新数组.
方法调用后, 原数组将发生改变.

> 参阅: sortBy

## [m] sorted#

### sorted(arr)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- returns { T[] }

按简单比较方式原地排序, 并返回排序后的新数组.
方法调用后, 原数组将 不 发生改变.

    let arr = [ 2, 3, 1, 20, 10 ];

    console.log(Arrayx.sorted(arr)); // [ 1, 2, 3, 10, 20 ]

    /* 启用内置对象扩展后. */
    console.log(arr.sorted()); /* 同上. */

    /* arr 不发生改变. */
    console.log(arr); // [ 2, 3, 1, 20, 10 ]

## [m] sortedBy#

### sortedBy(arr, selector)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- selector { (e: T) => U } - 条件选择器
- returns { T[] }

按一定条件原地排序, 并返回排序后的新数组.
方法调用后, 原数组将 不 发生改变.

> 参阅: sortBy

## [m] sortedDescending#

### sortedDescending(arr)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- returns { T[] }

按一定条件原地 降序 排序, 并返回排序后的新数组.
方法调用后, 原数组将 不 发生改变.

> 参阅: sortDescending

## [m] sortedByDescending#

### sortedByDescending(arr, selector)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- selector { (e: T) => U } - 条件选择器
- returns { T[] }

按一定条件原地 降序 排序, 并返回排序后的新数组.
方法调用后, 原数组将 不 发生改变.

> 参阅: sortByDescending

## [m] shuffle#

### shuffle(arr)#

`6.2.0` `xProto`

- arr { T[] } - 待处理数组
- returns { T[] }

按随机乱序方式原地排序, 并返回排序后的新数组.
方法调用后, 原数组将发生改变.

    /* 将元素随机乱序排序. */
    let arrA = [ 1, 2, 3, 4, 5, 6 ];
    console.log(Arrayx.shuffle(arrA)); /* e.g. [ 2, 4, 5, 1, 6, 3 ] */

    /* arrA 将发生改变. */
    console.log(arrA); /* 很可能不再是 [ 1, 2, 3, 4, 5, 6 ]. */

    /* 启用内置对象扩展后的使用方式. */
    console.log(arrA.shuffle()); /* 另一个随机的结果. */