Given a list of strings such as: apple01
, apple02
, and apple04
, banana02
, cherry01
, how would you come up with t
This could be the start of what you are looking for. I took a very similar approach as PetSerAl has done in his comment. I have made mine more verbose as it helps to take in what is happening here. Most of the explanation comes from comments in the code.
# Array of fruits/index values. Using string array as proof on concept.
$fruits = "apple01","apple02","apple04","banana02","cherry01"
# Regex -match the fruit name and index number. This also filters out lines that do not match the standard.
$fruityArray = $fruits | Where-Object{$_ -match '^(.+?)(\d+)$' } | ForEach-Object{
# Create a simple object that splits up the matched info into a fruit index object
[pscustomobject][ordered]@{
Fruit = $matches[1]
Index = [int]$matches[2]
}
}
# Group by fruit and then we can find the next available index within the groups
$fruityArray | Group-Object Fruit | ForEach-Object{
# For this fruit determine the next available index
$thisFruitGroup = $_
# Determine the highest index value. We add one in case all indexes are present from 1 to highest
$highestPossibleIndex = ($thisFruitGroup.Group.Index | Measure-Object -Maximum).Maximum + 1
# Check all possible indexes. Locating all that are free but filter the first one out
$nextAvailableIndex = 1..$highestPossibleIndex | Where-Object{$_ -notin $thisFruitGroup.Group.Index} | Select -First 1
# Take the fruit and add a padded index then pass that value to the pipeline.
'{0}{1:00}'-f $thisFruitGroup.Name, $nextAvailableIndex
}
We take the array of fruits and create an object array of fruit and indexes. Group those together by fruit and then determine the next available index based on all available indexes for that fruit. We add one to the highest possible index on the chance that they are all in use (no gaps). This is the case for cherry.
apple03
banana01
cherry02
Alternatively you could output the results to a variable and call the fruit you need from there if you don't need the whole list as output.
# Group by fruit and then we can find the next available index within the groups
$availableIndexes = $fruityArray | Group-Object Fruit | ForEach-Object{
# For this fruit determine the next available index
$thisFruitGroup = $_
# Determine the highest index value. We add one in case all indexes are present from 1 to highest
$highestPossibleIndex = ($thisFruitGroup.Group.Index | Measure-Object -Maximum).Maximum + 1
# Check all possible indexes. Locating all that are free but filter the first one out
$nextAvailableIndex = 1..$highestPossibleIndex | Where-Object{$_ -notin $thisFruitGroup.Group.Index} | Select -First 1
# Take the fruit and add a padded index then pass that value to the pipeline.
[pscustomobject][ordered]@{
Fruit = $thisFruitGroup.Name
Index = $nextAvailableIndex
String = '{0}{1:00}'-f $thisFruitGroup.Name, $nextAvailableIndex
}
}
$availableIndexes | Where-Object{$_.Fruit -eq "Apple"} | Select-Object -ExpandProperty String
Which would net the output of:
apple03