Найти следующий номер в последовательности - PullRequest
2 голосов
/ 20 июня 2019

Я работаю, чтобы найти следующий доступный номер в наборе чисел и у меня возникли проблемы.

Мой набор данных - это массив строк, который затем преобразуется в массив целых чисел. Исходный набор данных может иметь повторяющиеся номера.

Когда я пытаюсь найти следующий доступный номер, дубликаты, кажется, вызывают проблемы, дающие плохие результаты

$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

Наконец, $Available перечисляет 2 в качестве доступного номера, что неверно. 2 фактически используется дважды, и правильный ответ должен быть 3.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Преобразование ваших строк в числа можно выполнить с помощью простого 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 списковобъекты, которые являются уникальными для либо коллекции.

При наличии дубликатов в $used дубликаты также сообщаются как уникальные, так как $range не имеет дубликатов.

При -PassThru уникальные значения передаются без (очевидного) различия в отношении того, для какой коллекции входов они уникальны, так что в итоге вы получите комбинацию чисел, уникальных для любой коллекции, включающую оба числа, уникальные для $range и дубликатов, которые объясняют ваш симптом.

За счет предварительного удаления дубликатов из $used проблема устраняется, поскольку все уникальные значения гарантируютсяd только из $range.

1 голос
/ 20 июня 2019

Ответ на этот вопрос ранее: Удаление повторяющихся значений из массива PowerShell

Множество отличных вариантов ответа, но в основном:

$Used = $Used | select -uniq или другой вариант $Used | sort -uniq

0 голосов
/ 20 июня 2019

командлет Compare-Object всегда смущает меня [ blush ], поэтому я полностью избежал этого.[ ухмылка ] это работает путем ...

  • преобразования набора данных [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

output ...

3
7
8
9
10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...