You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell是否有内置方法高效搜索唯一已排序数组/集合并返回索引?

PowerShell中已排序唯一集合的高效搜索方案

你不需要自己实现二分查找逻辑,PowerShell可以直接调用.NET框架的内置工具来完成这个需求,以下是几种实用方案:

1. 直接用Array.BinarySearch处理已排序数组

PowerShell的数组本质是.NET的System.Array,可以直接调用静态方法[Array]::BinarySearch来做O(log n)效率的二分查找,找到后返回对应索引,未找到则返回负数(按位取反后是该值应该插入的位置)。

示例:基础类型数组

# 已排序的整数数组
$sortedArray = 2, 4, 6, 8, 10
$searchValue = 6

$index = [Array]::BinarySearch($sortedArray, $searchValue)
if ($index -ge 0) {
    "找到值,索引为: $index"
} else {
    "未找到目标值"
}

示例:自定义对象集合(SQL查询结果场景)

如果你的集合是SQL返回的自定义对象(比如带Id、Name属性),需要指定比较器来匹配排序规则(比如按Id排序的集合,就按Id比较):

# 模拟SQL返回的已排序唯一对象
$sortedObjects = @(
    [PSCustomObject]@{ Id = 101; Username = "user_a" },
    [PSCustomObject]@{ Id = 103; Username = "user_b" },
    [PSCustomObject]@{ Id = 105; Username = "user_c" }
)

# 目标匹配对象
$targetObj = [PSCustomObject]@{ Id = 103; Username = "user_b" }

# 创建比较器,按Id属性比较
$idComparer = [System.Collections.Generic.Comparer[PSCustomObject]]::Create({
    param($objA, $objB)
    $objA.Id.CompareTo($objB.Id)
})

$index = [Array]::BinarySearch($sortedObjects, $targetObj, $idComparer)
if ($index -ge 0) {
    "找到匹配对象,索引: $index,用户名: $($sortedObjects[$index].Username)"
} else {
    "未找到匹配对象"
}

2. 使用.NET已排序集合类型

如果需要频繁执行查找操作,可以提前将数据存入.NET的内置已排序集合,这些集合本身维护有序状态,查找效率更高:

SortedList<TKey, TValue>:键值对场景

适合以唯一键排序的场景,支持直接通过键查找值,还能通过IndexOfKey获取键对应的索引:

# 初始化SortedList,键为Id(整数类型),值为自定义对象
$sortedList = [System.Collections.Generic.SortedList[int, PSCustomObject]]::new()
$sortedObjects | ForEach-Object { $sortedList.Add($_.Id, $_) }

# 查找Id=103的对象
$targetId = 103
if ($sortedList.ContainsKey($targetId)) {
    $foundObj = $sortedList[$targetId]
    $index = $sortedList.IndexOfKey($targetId)
    "找到对象: $($foundObj.Username),索引: $index"
}

SortedSet<T>:元素存在性/匹配场景

如果只需要判断元素是否存在或获取匹配项,SortedSet<T>的查找效率也是O(log n),但它没有直接返回索引的方法:

# 初始化SortedSet,传入自定义比较器
$setComparer = [System.Collections.Generic.Comparer[PSCustomObject]]::Create({
    param($a, $b)
    $a.Id.CompareTo($b.Id)
})
$sortedSet = [System.Collections.Generic.SortedSet[PSCustomObject]]::new($setComparer)
$sortedObjects | ForEach-Object { $sortedSet.Add($_) }

# 检查目标对象是否存在
if ($sortedSet.Contains($targetObj)) {
    "找到匹配对象"
}

关键注意点

  • 所有方案的前提是集合必须严格按照你指定的规则排序,否则二分查找或已排序集合的逻辑会返回错误结果。
  • 自定义对象的比较器必须和集合的排序规则完全一致,比如集合按Id升序排序,比较器也要用Id的升序比较逻辑。

内容的提问来源于stack exchange,提问作者ornsio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 04:02:31