【问题标题】:Find next number in a sequence查找序列中的下一个数字
【发布时间】:2019-06-20 09:24:33
【问题描述】:

我正在寻找一组号码中的下一个可用号码,但遇到了麻烦。

我的数据集是一个字符串数组,然后将其转换为整数数组。原始数据集可能有重复的数字。

当我尝试查找下一个可用号码时,重复的号码似乎会导致产生不良结果的问题

$dataset = "0001","0002","0004","0006","2","5"

#Convert our strings to integers
[array]$Used = foreach($number in $dataset) {
   try {
         [int]::parse($number)
   } catch {
         Invoke-Expression -Command $number;
   }
}

[array]::sort($Used)

$range = 1..10
$Available = compare $range $Used -PassThru

我的结果是:

$Dataset = 
0001
0002
0004
0006
2
5

$Used = 
1
2
2
4
5
6

注意到$Used(已排序)显示2 是重复的:

$Available = 
2
3
7
8
9
10

最后$Available2 列为一个错误的可用号码。 2实际上用了两次,正确答案应该是3

有什么想法吗?

【问题讨论】:

  • $Available = compare $range $used -PassThru | where SideIndicator -eq '<='
  • $Available = Compare-object $range ($used|Sort-Object -Unique) -PassThru

标签: powershell


【解决方案1】:

这个问题之前已经回答过:Removing duplicate values from a PowerShell array

很多很棒的答案选项,但基本上:

$Used = $Used | select -uniq 或其他选择 $Used | sort -uniq

【讨论】:

    【解决方案2】:

    将字符串转换为数字可以通过一个简单的cast来完成:

    $dataset = "0001","0002","0004","0006","2","5"
    
    $numbers = [int[]] $dataset
    

    要对这些数字进行排序并消除重复项:

    $uniqueSortedNumbers = $numbers | Sort-Object -Unique
    

    要在结果列表中找到第一个可用的数字,或者可能是下一个更大的数字:

    # Find the first gap in the list of sorted numbers, if any.
    $nextAvailableNumber = 
      Compare-Object -PassThru $uniqueSortedNumbers (1..($uniqueSortedNumbers[-1])) |
        Select-Object -First 1 
    
    # If there was no gap, use the highest number + 1
    if ($null -eq $nextAvailableNumber) { 
      $nextAvailableNumber = $uniqueSortedNumbers[-1] + 1
    }
    

    至于你尝试了什么

    Compare-Object 列出 either 集合唯一的对象。

    由于$used 中有重复项,重复项也会报告为唯一,因为$range 没有重复对应项。

    使用-PassThru,唯一值的传递没有(明显)区分它们是唯一的输入集合,因此您最终会得到任一集合唯一的数字组合,包括两者 $range 独有的数字重复的数字,这解释了你的症状。

    通过预先消除来自$used 的重复项,可以避免该问题,因为所有唯一值都可以保证仅来自$range

    【讨论】:

      【解决方案3】:

      Compare-Object cmdlet 总是让我感到困惑 [blush],所以我完全避免了它。 [grin] 这个作品...

      • 将数据集[string]项目转换为[int]项目
      • 消除欺骗
      • 过滤不在已用数字列表中的目标范围数字

      这是代码...

      $DataSet = '0001','0002','0004','0006','2','5'
      $UsedNumbers = $DataSet.
          ForEach({[int]$_}) |
          Sort-Object -Unique
      
      $TargetRange = 1..10
      
      $AvailableNumbers = $TargetRange.
          Where({
              $_ -notin $UsedNumbers
              })
      
      $AvailableNumbers
      

      输出...

      3
      7
      8
      9
      10
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-07
        • 1970-01-01
        • 2016-03-12
        相关资源
        最近更新 更多